﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область ОписаниеПеременных

////////////////////////////////////////////////////////////////////////////////
// ИСПОЛЬЗУЕМЫЕ СОКРАЩЕНИЯ ИМЕН ПЕРЕМЕННЫХ (АББРЕВИАТУРЫ)
//
//  ПКО  - правило конвертации объектов.
//  ПКС  - правило конвертации свойств объектов.
//  ПКГС - правило конвертации группы свойств объектов.
//  ПКЗ  - правило конвертации значений объектов.
//  ПВД  - правило выгрузки данных.
//  ПОД  - правило очистки данных.

////////////////////////////////////////////////////////////////////////////////
// ЭКСПОРТНЫЕ ПЕРЕМЕННЫЕ

Перем КлючСообщенияЖурналаРегистрации Экспорт; // строка сообщения для фиксации ошибок в журнале регистрации.

Перем ВнешнееСоединение Экспорт; // Содержит глобальный контекст внешнего соединения или Неопределено.

Перем Запросы Экспорт; // Структура, содержащая используемые запросы.

////////////////////////////////////////////////////////////////////////////////
// ВСПОМОГАТЕЛЬНЫЕ ПЕРЕМЕННЫЕ МОДУЛЯ ДЛЯ НАПИСАНИЯ АЛГОРИТМОВ (ОБЩИЕ ДЛЯ ВЫГРУЗКИ И ЗАГРУЗКИ)

Перем Конвертация; // Структура свойств конвертации (Имя, Ид, обработчики событий обмена).

Перем Алгоритмы; // Структура, содержащая используемые алгоритмы.

Перем ДопОбработки; // Структура, содержащая используемые внешние обработки.

Перем Правила; // Структура, содержащая ссылки на ПКО.

Перем Менеджеры; // Соответствие, содержащее поля Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД, ПКО.

Перем МенеджерыДляПлановОбмена;

Перем ПараметрыДопОбработок; // Структура, содержащая параметры, используемых внешних обработок.

Перем ПараметрыИнициализированы; // Если Истина, то необходимые параметры конвертации проинициализированы.

Перем ФайлПротоколаДанных; // Файл для ведения протокола обмена данными.

Перем ФлагКомментироватьОбработкуОбъектов;

////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ ОТЛАДКИ ОБРАБОТЧИКОВ

Перем ОбработкаВыгрузки;
Перем ОбработкаЗагрузки;

////////////////////////////////////////////////////////////////////////////////
// ФЛАГИ НАЛИЧИЯ ГЛОБАЛЬНЫХ ОБРАБОТЧИКОВ СОБЫТИЙ

Перем ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта;
Перем ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта;

Перем ЕстьГлобальныйОбработчикПередКонвертациейОбъекта;

Перем ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта;
Перем ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта;

////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ ОБРАБОТОК ОБМЕНА (ОБЩИЕ ДЛЯ ВЫГРУЗКИ И ЗАГРУЗКИ)

Перем ТипСтрока;                  // Тип("Строка")

Перем ТипБулево;                  // Тип("Булево")

Перем ТипЧисло;                   // Тип("Число")

Перем ТипДата;                    // Тип("Дата")

Перем ТипУникальныйИдентификатор; // Тип("УникальныйИдентификатор")

Перем ТипХранилищеЗначения;       // Тип("ХранилищеЗначения")

Перем ТипДвоичныеДанные;          // Тип("ДвоичныеДанные")

Перем ТипВидДвиженияНакопления;   // Тип("ВидДвиженияНакопления")

Перем ТипУдалениеОбъекта;         // Тип("УдалениеОбъекта")

Перем ТипВидСчета;                // Тип("ВидСчета")

Перем ТипТип;                     // Тип("Тип")

Перем ТипСоответствие;            // Тип("Соответствие")

Перем ТипОписаниеТипов;           // Тип("ОписаниеТипов")

Перем ТипСтрока36;
Перем ТипСтрока255;

Перем ТипРегистрСоответствия;

Перем ТипУзлаXMLКонецЭлемента;
Перем ТипУзлаXMLНачалоЭлемента;
Перем ТипУзлаXMLТекст;

Перем ЗначениеПустаяДата;

Перем СообщенияОбОшибках; // Соответствие. Ключ - код ошибки,  Значение - описание ошибки.

////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ МОДУЛЯ ОБРАБОТКИ ВЫГРУЗКИ
 
Перем СчетчикНПП;                            // Число

Перем НППЗаписанногоВФайл;

// ТаблицаЗначений - шаблон для воссоздания структуры таблицы путем копирования
Перем ТаблицаПравилКонвертацииСвойств;       // ТаблицаЗначений

Перем XMLПравила;                            // Xml-Строка, содержащая описание правил обмена.

Перем СтрокаТиповДляПриемника;

Перем ПолеДокументыДляОтложенногоПроведения; // Таблица значений для проведения документов после загрузки данных.


// Соответствие для хранения дополнительных свойств документов после загрузки данных.
Перем СоответствиеДокументовДляОтложенногоПроведения; // Соответствие

Перем ПолеОбъектыДляОтложеннойЗаписи; // Соответствие для записи объектов ссылочных типов после загрузки данных.

Перем ФайлОбмена; // Последовательно записываемый/читаемый файл обмена.

Перем КоличествоОбъектовКВыгрузке; //Общее количество объектов подлежащих выгрузке.

////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ МОДУЛЯ ОБРАБОТКИ ЗАГРУЗКИ
 
Перем КоличествоВыполненныхОтложенныхДвиженийДокументов;
Перем НомерПоследнегоПоискаПоСсылке;
Перем ЧислоХранимыхВыгруженныхОбъектовПоТипам;
Перем СоответствиеДопПараметровПоиска;
Перем СоответствиеТиповИНазваниеОбъектов;
Перем СоответствиеПустыхЗначенийТипов;
Перем СоответствиеОписаниеТипов;
Перем СоответствиеПравилКонвертации; // Соответствие для определения правила конвертации объекта по типу этого объекта.

Перем ПолеНомерСообщения;
Перем ПолеНомерПринятогоСообщения;
Перем РазрешитьПроведениеДокумента;
Перем СтекВызововВыгрузкиДанных;
Перем ГлобальныйСтекНеЗаписанныхОбъектов;
Перем СоответствиеДанныхДляОбновленияВыгруженныхЭлементов;
Перем СобытияПослеЗагрузкиПараметров;
Перем МенеджерРегистраСоответствийОбъектов;
Перем ТекущийУровеньВложенностиВыгрузитьПоПравилу;
Перем РежимВизуальнойНастройкиОбмена;
Перем РежимЗагрузкиИнформацииОПравилахОбмена;
Перем ТаблицаРезультатовЗагрузкиИнформацииОПоляхПоиска;
Перем ИнформацияОПользовательскихПоляхПоискаПриВыгрузкеДанных;
Перем ИнформацияОПользовательскихПоляхПоискаПриЗагрузкеДанных;
Перем ЗапросСоответствияОбъектовИнформационныхБаз;
Перем ЕстьКорректировкаИнформацииОРегистрацииОбъекта;
Перем ЕстьИнформацияОРегистрацииОбъекта;
Перем УзелОбменаЗагрузкаДанныхОбъект;

Перем ПолеОбработкаДляЗагрузкиДанных;
Перем КоличествоОбъектовКЗагрузке;
Перем РазмерФайлаСообщенияОбмена;

////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ ДЛЯ ЗНАЧЕНИЙ СВОЙСТВ

Перем ПолеФлагОшибки;
Перем ПолеРезультатВыполненияОбмена;
Перем ПолеСостояниеОбменаДанными;

// Соответствие с таблицами значений данных из сообщения обмена; 
// Ключ - ИмяТипа (Строка); Значение - таблица с данными объектов (ТаблицаЗначений).
Перем ПолеТаблицыДанныхСообщенияОбмена; // Соответствие

Перем ПолеТаблицаДанныхЗаголовкаПакета; // Таблица значений с данными из файла заголовка пакета сообщений обмена.

Перем ПолеСтрокаСообщенияОбОшибке; // Строка - переменная содержит строку с сообщением об ошибке.

Перем ПолеСоответствиеТиповДанныхДляЗагрузки;

Перем ПолеСчетчикЗагруженныхОбъектов; // Счетчик загруженных объектов.

Перем ПолеСчетчикВыгруженныхОбъектов; // Счетчик выгруженных объектов.

Перем ПолеПриоритетыРезультатовОбмена; // Массив - приоритеты результатов обмена данными по убыванию.

// Соответствие: Ключ - ОбъектМетаданных; Значение - ТаблицаЗначений -
// таблица описания свойств объекта метаданных.
Перем ПолеТаблицыОписанийСвойствОбъектов; // Соответствие

Перем ПолеВыгруженныеПоСсылкеОбъекты; // Массив объектов, выгруженных по ссылке. Элементы массива уникальны.

Перем ПолеСозданныеПриВыгрузкеОбъекты; // Массив объектов, созданных при выгрузке. Элементы массива уникальны.

// Соответствие, где Ключ - ОбъектМетаданных, а Значение - признак выгрузки объекта по ссылке.
// Истина - надо выгружать объект по ссылке, Ложь - не надо.
Перем ПолеВыгружаемыеПоСсылкеОбъектыМетаданных; // Соответствие

// ТаблицаЗначений - содержит правила регистрации объектов (правила только
// с видом "Фильтр разрешенных объектов" и для текущего плана обмена).
Перем ПолеПравилаРегистрацииОбъектов; // ТаблицаЗначений

Перем ПолеИмяПланаОбмена;

Перем ПолеСвойстваУзлаПланаОбмена;

Перем ПолеВерсияФорматаВходящегоСообщенияОбмена;

Перем ПоместитьСообщениеВАрхивПриВнешнемСоединении;
Перем ВременныйКаталогДляСборкиАрхива;
Перем НомерПакета;

#КонецОбласти

#Область ПрограммныйИнтерфейс

#Область ЭкспортныеСвойства

// Функция-свойство: номер принятого сообщения обмена данными.
//
// Возвращаемое значение:
//  Число - номер принятого сообщения обмена данными.
//
Функция НомерПринятогоСообщения() Экспорт
	
	Если ТипЗнч(ПолеНомерПринятогоСообщения) <> Тип("Число") Тогда
		
		ПолеНомерПринятогоСообщения = 0;
		
	КонецЕсли;
	
	Возврат ПолеНомерПринятогоСообщения;
	
КонецФункции

#КонецОбласти

#Область РаботаСДанными

// Возвращает строку - имя переданного значения перечисления.
// Функция может быть использована в обработчиках событий, программный код 
// которых хранится в правила обмена данными. Вызывается методом Выполнить().
// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации 
// не является ошибкой проверки конфигурации.
//
// Параметры:
//  Значение - ПеречислениеСсылка - значение перечисления.
//
// Возвращаемое значение:
//   Строка - имя переданного значения перечисления.
//
Функция одИмяЗначенияПеречисления(Значение) Экспорт

	ОбъектМД = Значение.Метаданные();
	
	МенеджерПеречисления = Перечисления[ОбъектМД.Имя]; // ПеречислениеМенеджер
	ИндексЗначения = МенеджерПеречисления.Индекс(Значение);

	Возврат ОбъектМД.ЗначенияПеречисления.Получить(ИндексЗначения).Имя;

КонецФункции

#КонецОбласти

#Область ПроцедурыРаботыСПравиламиОбмена

// Устанавливает значения параметров в структуре Параметры 
// по таблице ТаблицаНастройкиПараметров.
//
Процедура УстановитьПараметрыИзДиалога() Экспорт

	Для Каждого СтрокаТаблицы Из ТаблицаНастройкиПараметров Цикл
		Параметры.Вставить(СтрокаТаблицы.Имя, СтрокаТаблицы.Значение);
	КонецЦикла;

КонецПроцедуры

#КонецОбласти

#Область ОтправкаДанных

// Производит выгрузку объекта в соответствии с указанным правилом конвертации.
//
// Параметры:
//  Источник				 - Произвольный -произвольный источник данных.
//  Приемник				 - ЗаписьXML - xml-узел объекта приемника.
//  ВходящиеДанные			 - Произвольный - вспомогательные данные, передаваемые правилу
//                             для выполнения конвертации.
//  ИсходящиеДанные			 - Произвольный - произвольные вспомогательные данные, передаваемые правилам
//                             конвертации свойств.
//  ИмяПКО					 - Строка - имя правила конвертации, согласно которому осуществляется выгрузка.
//  УзелСсылки				 - ЗаписьXML - xml-узел ссылки объекта приемника.
//  ТолькоПолучитьУзелСсылки - Булево - если Истина, то выгрузка объекта не производится, только формируется
//                             xml-узел ссылки.
//  ПКО                      - СтрокаТаблицыЗначений - строка таблицы правил конвертации.
//  ВыгружатьСсылкиУПодчиненныхОбъектов - Булево - если Истина то выгружаются ссылки у подчиненных объектов.
//  ВыгрузкаСтрокиНабораЗаписейРегистра - Булево - если Истина то происходит выгрузка  строки набора записей.
//  УзелПредка				 - ЗаписьXML - xml-узел предка объекта приемника.
//  ИмяКонстантыДляВыгрузки  - Строка - значение, которое следует записать в атрибут ИмяКонстанты.
//  ЭтоВыгружаетсяОбъект     - Булево - признак того что выгружается объект.
//  ЭтоПравилоСГлобальнойВыгрузкойОбъектов - Булево - признак глобальной выгрузки объектов.
//  НеИспользоватьПравилоСГлобальнойВыгрузкойИНеЗапоминатьВыгруженные - Булево - не используется.
//  СтекВыгрузкиОбъекта      - Массив из ЛюбаяСсылка - содержит сведения о вышестоящих объектах выгрузки.
//
// Возвращаемое значение:
//   ЗаписьXML - xml-узел ссылки или значение приемника.
//
Функция ВыгрузитьПоПравилу(
		Источник = Неопределено,
		Приемник = Неопределено,
		ВходящиеДанные = Неопределено,
		ИсходящиеДанные = Неопределено,
		ИмяПКО = "",
		УзелСсылки = Неопределено,
		ТолькоПолучитьУзелСсылки = Ложь,
		ПКО = Неопределено,
		ВыгружатьСсылкиУПодчиненныхОбъектов = Истина,
		ВыгрузкаСтрокиНабораЗаписейРегистра = Ложь,
		УзелПредка = Неопределено,
		ИмяКонстантыДляВыгрузки = "",
		ЭтоВыгружаетсяОбъект = Неопределено,
		ЭтоПравилоСГлобальнойВыгрузкойОбъектов = Ложь,
		НеИспользоватьПравилоСГлобальнойВыгрузкойИНеЗапоминатьВыгруженные = Ложь,
		СтекВыгрузкиОбъекта = Неопределено) Экспорт
	
	ОпределитьПКОПоПараметрам(ПКО, Источник, ИмяПКО);
	
	Если ПКО = Неопределено Тогда
		
		ЗП = ЗаписьПротоколаОбмена(45);
		
		ЗП.Объект = Источник;
		ЗП.ТипОбъекта = ТипЗнч(Источник);
		
		ЗаписатьВПротоколВыполнения(45, ЗП, Истина); // не найдено ПКО
		Возврат Неопределено;
		
	КонецЕсли;
	
	ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу + 1;
	
	Если ФлагКомментироватьОбработкуОбъектов Тогда
		
		Попытка
			ИсточникВСтроку = Строка(Источник);
		Исключение
			ИсточникВСтроку = " ";
		КонецПопытки;
		
		ИмяДействия = ?(ТолькоПолучитьУзелСсылки, НСтр("ru = 'Конвертация ссылки на объект'"), НСтр("ru = 'Конвертация объекта'"));
		
		ТекстСообщения = НСтр("ru = '[ИмяДействия]: [Объект]([ТипОбъекта]), ПКО: [ПКО](НаименованиеПКО)'");
		ТекстСообщения = СтрЗаменить(ТекстСообщения, "[ИмяДействия]", ИмяДействия);
		ТекстСообщения = СтрЗаменить(ТекстСообщения, "[Объект]", ИсточникВСтроку);
		ТекстСообщения = СтрЗаменить(ТекстСообщения, "[ТипОбъекта]", ТипЗнч(Источник));
		ТекстСообщения = СтрЗаменить(ТекстСообщения, "[ПКО]", СокрЛП(ИмяПКО));
		ТекстСообщения = СтрЗаменить(ТекстСообщения, "[НаименованиеПКО]", СокрЛП(ПКО.Наименование));
		
		ЗаписатьВПротоколВыполнения(ТекстСообщения, , Ложь, ТекущийУровеньВложенностиВыгрузитьПоПравилу + 1, 7);
		
	КонецЕсли;
	
	ЭтоПравилоСГлобальнойВыгрузкойОбъектов = Ложь;
	
	Если СтекВыгрузкиОбъекта = Неопределено Тогда
		СтекВыгрузкиОбъекта = Новый Массив;
	КонецЕсли;
	
	СвойстваДляПереноса = Новый Структура("Ссылка");
	Если Источник <> Неопределено И ТипЗнч(Источник) <> Тип("Строка") Тогда
		ЗаполнитьЗначенияСвойств(СвойстваДляПереноса, Источник);
	КонецЕсли;
	ИсточникСсылка = СвойстваДляПереноса.Ссылка;
	
	ОбъектВыгружаетсяПоСсылкеИзСамогоСебя = Ложь;
	Если ЗначениеЗаполнено(ИсточникСсылка) Тогда
		ПорядковыйНомерВСтеке = СтекВыгрузкиОбъекта.Найти(ИсточникСсылка);
		ОбъектВыгружаетсяПоСсылкеИзСамогоСебя = ПорядковыйНомерВСтеке <> Неопределено;
	КонецЕсли;
	
	СтекВыгрузкиОбъекта.Добавить(ИсточникСсылка);
	
	// Циклическая ссылка на объект и
	// дополнительно учитываем настройку в правилах.
	ЗапоминатьВыгруженные = ОбъектВыгружаетсяПоСсылкеИзСамогоСебя И (ПКО.ЗапоминатьВыгруженные);
	
	ВыгруженныеОбъекты          = ПКО.Выгруженные;
	ВсеОбъектыВыгружены         = ПКО.ВсеОбъектыВыгружены;
	НеЗамещатьОбъектПриЗагрузке = ПКО.НеЗамещать;
	НеСоздаватьЕслиНеНайден     = ПКО.НеСоздаватьЕслиНеНайден;
	ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD     = ПКО.ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD;
	НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = ПКО.НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике;
	ПриоритетОбъектовОбмена = ПКО.ПриоритетОбъектовОбмена;
	
	РегистрироватьОбъектНаУзлеОтправителе = Ложь;
	
	ПрефиксАвтонумерации		= "";
	РежимЗаписи     			= "";
	РежимПроведения 			= "";
	СписокВременныхФайлов = Неопределено;

   	ИмяТипа          = "";
	ВыгружатьСвойстваОбъекта = Истина;
	
	СтруктураСвойств = НайтиСтруктуруСвойствПоПараметрам(ПКО, Источник);
			
	Если СтруктураСвойств <> Неопределено Тогда
		ИмяТипа = СтруктураСвойств.ИмяТипа;
	КонецЕсли;

	КлючВыгружаемыхДанных = ИмяПКО;
	
	Если ЗначениеЗаполнено(ИмяТипа) Тогда
		
		ЭтоНеСсылочныйТип = ИмяТипа = "Константы"
			Или ИмяТипа = "РегистрСведений"
			Или ИмяТипа = "РегистрНакопления"
			Или ИмяТипа = "РегистрБухгалтерии"
			Или ИмяТипа = "РегистрРасчета";
		
	Иначе
		
		Если ТипЗнч(Источник) = Тип("Структура") Тогда
			ЭтоНеСсылочныйТип = Не Источник.Свойство("Ссылка");
		Иначе
			ЭтоНеСсылочныйТип = Истина;
		КонецЕсли;
		
	КонецЕсли;
	
	Если ЭтоНеСсылочныйТип 
		ИЛИ ПустаяСтрока(ИмяТипа) Тогда
		
		ЗапоминатьВыгруженные = Ложь;
		
	ИначеЕсли ПКО.Владелец().Колонки.Найти("ОбъектСДвижениями") <> Неопределено
		И ПКО.ОбъектСДвижениями = Истина Тогда
		
		// Если объект выгружаем с движениями по регистрам - проводить не нужно
		РежимЗаписи = "Запись";
		
	КонецЕсли;
	
	СсылкаНаИсточник = Неопределено;
	ВыгружаетсяОбъект = ЭтоВыгружаетсяОбъект;
	
	Если (Источник <> Неопределено) 
		И НЕ ЭтоНеСсылочныйТип Тогда
		
		Если ВыгружаетсяОбъект = Неопределено Тогда
			// Если не указано что выгружается, то считаем что выгружается объект.
			ВыгружаетсяОбъект = Истина;	
		КонецЕсли;
		
		СсылкаНаИсточник = ОпределитьСсылкуПоОбъектуИлиСсылке(Источник, ВыгружаетсяОбъект);
		Если ЗапоминатьВыгруженные Тогда
			КлючВыгружаемыхДанных = ОпределитьВнутреннеПредставлениеДляПоиска(СсылкаНаИсточник, СтруктураСвойств);
		КонецЕсли;
		
	Иначе
		
		ВыгружаетсяОбъект = Ложь;
			
	КонецЕсли;
	
	// Переменная для хранения имени предопределенного элемента.
	ИмяПредопределенногоЭлемента = Неопределено;
	
	// Глобальный обработчик ПередКонвертациейОбъекта.
	Отказ = Ложь;
	Если ЕстьГлобальныйОбработчикПередКонвертациейОбъекта Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ПараметрыОбработчика = Новый Массив();
				ПараметрыОбработчика.Добавить(ФайлОбмена);
				ПараметрыОбработчика.Добавить(Источник);
				ПараметрыОбработчика.Добавить(ВходящиеДанные);
				ПараметрыОбработчика.Добавить(ИсходящиеДанные);
				ПараметрыОбработчика.Добавить(ИмяПКО);
				ПараметрыОбработчика.Добавить(ПКО);
				ПараметрыОбработчика.Добавить(ВыгруженныеОбъекты);
				ПараметрыОбработчика.Добавить(Отказ);
				ПараметрыОбработчика.Добавить(КлючВыгружаемыхДанных);
				ПараметрыОбработчика.Добавить(ЗапоминатьВыгруженные);
				ПараметрыОбработчика.Добавить(НеЗамещатьОбъектПриЗагрузке);
				ПараметрыОбработчика.Добавить(ВсеОбъектыВыгружены);
				ПараметрыОбработчика.Добавить(ТолькоПолучитьУзелСсылки);
				ПараметрыОбработчика.Добавить(Приемник);
				ПараметрыОбработчика.Добавить(РежимЗаписи);
				ПараметрыОбработчика.Добавить(РежимПроведения);
				ПараметрыОбработчика.Добавить(НеСоздаватьЕслиНеНайден);
				
				ВыполнитьОбработчик_Конвертация_ПередКонвертациейОбъекта(ПараметрыОбработчика);
				
				ФайлОбмена = ПараметрыОбработчика[0];
				Источник = ПараметрыОбработчика[1];
				ВходящиеДанные = ПараметрыОбработчика[2];
				ИсходящиеДанные = ПараметрыОбработчика[3];
				ИмяПКО = ПараметрыОбработчика[4];
				ПКО = ПараметрыОбработчика[5];
				ВыгруженныеОбъекты = ПараметрыОбработчика[6];
				Отказ = ПараметрыОбработчика[7];
				КлючВыгружаемыхДанных = ПараметрыОбработчика[8];
				ЗапоминатьВыгруженные = ПараметрыОбработчика[9];
				НеЗамещатьОбъектПриЗагрузке = ПараметрыОбработчика[10];
				ВсеОбъектыВыгружены = ПараметрыОбработчика[11];
				ТолькоПолучитьУзелСсылки = ПараметрыОбработчика[12];
				Приемник = ПараметрыОбработчика[13];
				РежимЗаписи = ПараметрыОбработчика[14];
				РежимПроведения = ПараметрыОбработчика[15];
				НеСоздаватьЕслиНеНайден = ПараметрыОбработчика[16];
				
			Иначе
				
				Выполнить(Конвертация.ПередКонвертациейОбъекта);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(64, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ПКО, Источник, НСтр("ru = 'ПередКонвертациейОбъекта (глобальный)'"));
		КонецПопытки;
		
		Если Отказ Тогда	//	Отказ от дальнейшей обработки правила.
			ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
			Возврат Приемник;
		КонецЕсли;
		
	КонецЕсли;
	
	// Обработчик ПередВыгрузкой
	Если ПКО.ЕстьОбработчикПередВыгрузкой Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПКО_ПередВыгрузкойОбъекта(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО, ПКО,
															  ВыгруженныеОбъекты, Отказ, КлючВыгружаемыхДанных, ЗапоминатьВыгруженные,
															  НеЗамещатьОбъектПриЗагрузке, ВсеОбъектыВыгружены, ТолькоПолучитьУзелСсылки,
															  Приемник, РежимЗаписи, РежимПроведения, НеСоздаватьЕслиНеНайден);
				
			Иначе
				
				Выполнить(ПКО.ПередВыгрузкой);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(41, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ПКО, Источник, "ПередВыгрузкойОбъекта");
		КонецПопытки;
		
		Если Отказ Тогда	//	Отказ от дальнейшей обработки правила.
			ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
			Возврат Приемник;
		КонецЕсли;
		
	КонецЕсли;
	
	СтрокаВСтекеВыгрузки = Неопределено;
	
	НужноОбновитьЛокальныйКЭШВыгруженныхОбъектов = Ложь;
	ЗначениеСсылкиВДругойИБ = "";

	// Возможно такие данные уже выгружались.
	Если Не ВсеОбъектыВыгружены Тогда
		
		НПП = 0;
		
		Если ЗапоминатьВыгруженные Тогда
			
			СтрокаВыгруженныхОбъектов = ВыгруженныеОбъекты.Найти(КлючВыгружаемыхДанных, "Ключ");
			
			Если СтрокаВыгруженныхОбъектов <> Неопределено Тогда
				
				СтрокаВыгруженныхОбъектов.КоличествоОбращений = СтрокаВыгруженныхОбъектов.КоличествоОбращений + 1;
				СтрокаВыгруженныхОбъектов.НомерПоследнегоОбращения = СчетчикНПП;
				
				Если ТолькоПолучитьУзелСсылки Тогда
					
					ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
					Если СтрНайти(СтрокаВыгруженныхОбъектов.УзелСсылки, "<Ссылка") > 0
						И НППЗаписанногоВФайл >= СтрокаВыгруженныхОбъектов.НППСсылки Тогда
						Возврат СтрокаВыгруженныхОбъектов.НППСсылки;
					Иначе
						Возврат СтрокаВыгруженныхОбъектов.УзелСсылки;
					КонецЕсли;
					
				КонецЕсли;
				
				НомерВыгруженнойСсылки = СтрокаВыгруженныхОбъектов.НППСсылки;
				
				Если НЕ СтрокаВыгруженныхОбъектов.ВыгруженаТолькоСсылка Тогда
					
					ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
					Возврат СтрокаВыгруженныхОбъектов.УзелСсылки;
					
				Иначе
					
					СтрокаВСтекеВыгрузки = КоллекцияСтекВызововВыгрузкиДанных().Найти(КлючВыгружаемыхДанных, "Ссылка");
				
					Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
						ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
						Возврат Неопределено;
					КонецЕсли;
					
					СтрокаВСтекеВыгрузки = КоллекцияСтекВызововВыгрузкиДанных().Добавить();
					СтрокаВСтекеВыгрузки.Ссылка = КлючВыгружаемыхДанных;
					
					НПП = НомерВыгруженнойСсылки;
					
				КонецЕсли;
				
			КонецЕсли;
			
		КонецЕсли;
		
		Если НПП = 0 Тогда
			
			СчетчикНПП = СчетчикНПП + 1;
			НПП        = СчетчикНПП;
			
			
			// Это позволит избежать циклических ссылок.
			Если ЗапоминатьВыгруженные Тогда
				
				Если СтрокаВыгруженныхОбъектов = Неопределено Тогда
					
					Если НЕ ЭтоПравилоСГлобальнойВыгрузкойОбъектов
						И НЕ НужноОбновитьЛокальныйКЭШВыгруженныхОбъектов
						И ВыгруженныеОбъекты.Количество() > ЧислоХранимыхВыгруженныхОбъектовПоТипам Тогда
						
						НужноОбновитьЛокальныйКЭШВыгруженныхОбъектов = Истина;
						СоответствиеДанныхДляОбновленияВыгруженныхЭлементов.Вставить(ПКО.Приемник, ПКО);
						
					КонецЕсли;
					
					СтрокаВыгруженныхОбъектов = ВыгруженныеОбъекты.Добавить();
					
				КонецЕсли;
				
				СтрокаВыгруженныхОбъектов.Ключ = КлючВыгружаемыхДанных;
				СтрокаВыгруженныхОбъектов.УзелСсылки = НПП;
				СтрокаВыгруженныхОбъектов.НППСсылки = НПП;
				СтрокаВыгруженныхОбъектов.НомерПоследнегоОбращения = НПП;
				
				Если ТолькоПолучитьУзелСсылки Тогда
					
					СтрокаВыгруженныхОбъектов.ВыгруженаТолькоСсылка = Истина;
					
				Иначе
					
					СтрокаВСтекеВыгрузки = КоллекцияСтекВызововВыгрузкиДанных().Добавить();
					СтрокаВСтекеВыгрузки.Ссылка = КлючВыгружаемыхДанных;
					
				КонецЕсли;
				
			КонецЕсли;
				
		КонецЕсли;
		
	КонецЕсли;
	
	СоответствиеЗначений = ПКО.ЗначенияПредопределенныхДанных;
	КоличествоЭлементовСоответствияЗначений = СоответствиеЗначений.Количество();
	
	// Обработка соответствий предопределенных элементов.
	Если ИмяПредопределенногоЭлемента = Неопределено Тогда
		
		Если СтруктураСвойств <> Неопределено
			И КоличествоЭлементовСоответствияЗначений > 0
			И СтруктураСвойств.ВозможенПоискПоПредопределенным Тогда
			
			Попытка
				ИмяПредопределенногоИсточник = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаИсточник, "ИмяПредопределенныхДанных");
			Исключение
				ИмяПредопределенногоИсточник = "";
			КонецПопытки;
			
		Иначе
			
			ИмяПредопределенногоИсточник = "";
			
		КонецЕсли;
		
		Если НЕ ПустаяСтрока(ИмяПредопределенногоИсточник)
			И КоличествоЭлементовСоответствияЗначений > 0 Тогда
			
			ИмяПредопределенногоЭлемента = СоответствиеЗначений[СсылкаНаИсточник];
			
		Иначе
			ИмяПредопределенногоЭлемента = Неопределено;
		КонецЕсли;
		
	КонецЕсли;
	
	Если ИмяПредопределенногоЭлемента <> Неопределено Тогда
		КоличествоЭлементовСоответствияЗначений = 0;
	КонецЕсли;
	
	НеНужноВыгружатьПоСоответствиюЗначений = (КоличествоЭлементовСоответствияЗначений = 0);
	
	Если Не НеНужноВыгружатьПоСоответствиюЗначений Тогда
		
		// Если нет объекта в соответствии значений - выгружаем его штатным образом.
		УзелСсылки = СоответствиеЗначений[СсылкаНаИсточник];
		Если УзелСсылки = Неопределено Тогда
			
			// Возможно это конвертация из перечисления в перечисление и мы просто не нашли по.
			// ПКЗ нужное свойство - тогда просто выгружаем пустую ссылку и все.
			Если СтруктураСвойств.ИмяТипа = "Перечисление"
				И СтрНайти(ПКО.Приемник, "ПеречислениеСсылка.") > 0 Тогда
				
				// Это может быть ссылка из удаленного расширения, тогда ошибку конвертации не регистрируем.
				Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(СсылкаНаИсточник))
					И ОбщегоНазначения.СсылкаСуществует(СсылкаНаИсточник) Тогда
					// Записываем ошибку в протокол выполнения.
					ЗП = ЗаписьПротоколаОбмена();
					ЗП.ИмяПКО              = ИмяПКО;
					ЗП.Значение            = Источник;
					ЗП.ТипЗначения         = СтруктураСвойств.ТипСсылкиСтрокой;
					ЗП.КСообщенияОбОшибках = 71;
					ЗП.Текст               = НСтр("ru = 'В правиле конвертации значений (ПКЗ) сопоставьте значение Источника значению Приемника.
														|Если подходящего значения приемника нет, то укажите пустое значение.'");
					//
					ЗаписатьВПротоколВыполнения(71, ЗП);
				КонецЕсли;
				
				Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
					СтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки);				
				КонецЕсли;
				
				ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
				
				Возврат Неопределено;
				
			Иначе
				
				НеНужноВыгружатьПоСоответствиюЗначений = Истина;
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
	НЕВыгружатьПодчиненныеОбъекты = ТолькоПолучитьУзелСсылки ИЛИ НЕ ВыгружатьСсылкиУПодчиненныхОбъектов;
	
	НужноЗапоминатьОбъект = ЗапоминатьВыгруженные И (Не ВсеОбъектыВыгружены);
	
	Если НеНужноВыгружатьПоСоответствиюЗначений Тогда
		
		Если ПКО.СвойстваПоиска.Количество() > 0 
			ИЛИ ИмяПредопределенногоЭлемента <> Неопределено Тогда
			
			//	Формируем узел ссылки
			УзелСсылки = СоздатьУзел("Ссылка");
						
			Если НужноЗапоминатьОбъект Тогда
				
				Если ЭтоПравилоСГлобальнойВыгрузкойОбъектов Тогда
					УстановитьАтрибут(УзелСсылки, "ГНпп", НПП);
				Иначе
					УстановитьАтрибут(УзелСсылки, "Нпп", НПП);
				КонецЕсли;
				
			КонецЕсли;
			
			Если НеСоздаватьЕслиНеНайден Тогда
				УстановитьАтрибут(УзелСсылки, "НеСоздаватьЕслиНеНайден", НеСоздаватьЕслиНеНайден);
			КонецЕсли;
			
			Если ПКО.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли Тогда
				УстановитьАтрибут(УзелСсылки, "ПродолжитьПоиск", Истина);
			КонецЕсли;
			
			Если РегистрироватьОбъектНаУзлеОтправителе Тогда
				УстановитьАтрибут(УзелСсылки, "РегистрироватьОбъектНаУзлеОтправителе", РегистрироватьОбъектНаУзлеОтправителе);
			КонецЕсли;
			
			ЗаписатьПриоритетОбъектовОбмена(ПриоритетОбъектовОбмена, УзелСсылки);
			
			Если НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике Тогда
				УстановитьАтрибут(УзелСсылки, "НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике", НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике);				
			КонецЕсли;
			
			Если ВыгружатьСвойстваОбъекта = Истина Тогда
			
				ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКО.СвойстваПоиска, 
					УзелСсылки, , ИмяПредопределенногоЭлемента, Истина, 
					Истина, ВыгружаетсяОбъект, КлючВыгружаемыхДанных, , ЗначениеСсылкиВДругойИБ,,, СтекВыгрузкиОбъекта);
					
			КонецЕсли;
			
			УзелСсылки.ЗаписатьКонецЭлемента();
			УзелСсылки = УзелСсылки.Закрыть();
			
			Если НужноЗапоминатьОбъект Тогда
				
				СтрокаВыгруженныхОбъектов.УзелСсылки = УзелСсылки;
				
			КонецЕсли;
			
		Иначе
			УзелСсылки = НПП;
		КонецЕсли;
		
	Иначе
		
		// Поиск в соответствии значений по ПКЗ.
		Если УзелСсылки = Неопределено Тогда
			
			// Записываем ошибку в протокол выполнения.
			ЗП = ЗаписьПротоколаОбмена();
			ЗП.ИмяПКО              = ИмяПКО;
			ЗП.Значение            = Источник;
			ЗП.ТипЗначения         = ТипЗнч(Источник);
			ЗП.КСообщенияОбОшибках = 71;
			
			ЗаписатьВПротоколВыполнения(71, ЗП);
			
			Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
				СтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки);				
			КонецЕсли;
			
			ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
			Возврат Неопределено;
		КонецЕсли;
		
		Если ЗапоминатьВыгруженные Тогда
			СтрокаВыгруженныхОбъектов.УзелСсылки = УзелСсылки;			
		КонецЕсли;
		
		Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
			СтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки);				
		КонецЕсли;
		
		ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
		Возврат УзелСсылки;
		
	КонецЕсли;

		
	Если ТолькоПолучитьУзелСсылки
		Или ВсеОбъектыВыгружены Тогда
		
		Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
			СтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки);				
		КонецЕсли;
		
		ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
		Возврат УзелСсылки;
		
	КонецЕсли; 

	Если Приемник = Неопределено Тогда
		
		Приемник = СоздатьУзел("Объект");
		
		Если НЕ ВыгрузкаСтрокиНабораЗаписейРегистра Тогда
			
			Если ЭтоПравилоСГлобальнойВыгрузкойОбъектов Тогда
				УстановитьАтрибут(Приемник, "ГНпп", НПП);
			Иначе
				УстановитьАтрибут(Приемник, "Нпп", НПП);
			КонецЕсли;
			
			УстановитьАтрибут(Приемник, "Тип", 			ПКО.Приемник);
			УстановитьАтрибут(Приемник, "ИмяПравила",	ПКО.Имя);
			
			Если НЕ ПустаяСтрока(ИмяКонстантыДляВыгрузки) Тогда
				
				УстановитьАтрибут(Приемник, "ИмяКонстанты", ИмяКонстантыДляВыгрузки);
				
			КонецЕсли;
			
			ЗаписатьПриоритетОбъектовОбмена(ПриоритетОбъектовОбмена, Приемник);
			
			Если НеЗамещатьОбъектПриЗагрузке Тогда
				УстановитьАтрибут(Приемник, "НеЗамещать",	"true");
			КонецЕсли;
			
			Если Не ПустаяСтрока(ПрефиксАвтонумерации) Тогда
				УстановитьАтрибут(Приемник, "ПрефиксАвтонумерации",	ПрефиксАвтонумерации);
			КонецЕсли;
			
			Если Не ПустаяСтрока(РежимЗаписи) Тогда
				
				УстановитьАтрибут(Приемник, "РежимЗаписи",	РежимЗаписи);
				Если Не ПустаяСтрока(РежимПроведения) Тогда
					УстановитьАтрибут(Приемник, "РежимПроведения",	РежимПроведения);
				КонецЕсли;
				
			КонецЕсли;
			
			Если ТипЗнч(УзелСсылки) <> ТипЧисло Тогда
				ДобавитьПодчиненный(Приемник, УзелСсылки);
			КонецЕсли;
		
		КонецЕсли;
		
	КонецЕсли;

	// Обработчик ПриВыгрузке
	СтандартнаяОбработка = Истина;
	Отказ = Ложь;
	
	Если ПКО.ЕстьОбработчикПриВыгрузке Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПКО_ПриВыгрузкеОбъекта(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО,
														   ПКО, ВыгруженныеОбъекты, КлючВыгружаемыхДанных, Отказ,
														   СтандартнаяОбработка, Приемник, УзелСсылки);
				
			Иначе
				
				Выполнить(ПКО.ПриВыгрузке);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(42, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ПКО, Источник, "ПриВыгрузкеОбъекта");
		КонецПопытки;
				
		Если Отказ Тогда	//	Отказ от записи объекта в файл.
			
			Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
				СтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки);				
			КонецЕсли;
			
			ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
			Возврат УзелСсылки;
		КонецЕсли;
		
	КонецЕсли;

	// Выгрузка свойств
	Если СтандартнаяОбработка Тогда
		
		Если НЕ ПустаяСтрока(ИмяКонстантыДляВыгрузки) Тогда
			
			МассивСвойствДляВыгрузки = Новый Массив();
			
			СтрокаТаблицы = ПКО.Свойства.Найти(ИмяКонстантыДляВыгрузки, "Источник");
			
			Если СтрокаТаблицы <> Неопределено Тогда
				МассивСвойствДляВыгрузки.Добавить(СтрокаТаблицы);
			КонецЕсли;
			
		Иначе
			
			МассивСвойствДляВыгрузки = ПКО.Свойства;
			
		КонецЕсли;
		
		Если ВыгружатьСвойстваОбъекта Тогда
		
			ВыгрузитьСвойства(
				Источник,                 // Источник
				Приемник,                 // Приемник
				ВходящиеДанные,           // ВходящиеДанные
				ИсходящиеДанные,          // ИсходящиеДанные
				ПКО,                      // ПКО
				МассивСвойствДляВыгрузки, // КоллекцияПКС
				,                         // УзелКоллекцииСвойств = Неопределено
				,                         // ОбъектКоллекции = Неопределено
				,                         // ИмяПредопределенногоЭлемента = Неопределено
				Истина,                   // Знач ВыгрузитьТолькоСсылку = Истина
				Ложь,                     // Знач ЭтоВыгрузкаСсылки = Ложь
				ВыгружаетсяОбъект,        // Знач ВыгружаетсяОбъект = Ложь
				КлючВыгружаемыхДанных,    // КлючПоискаСсылки = ""
				,                         // НеИспользоватьПравилаСГлобальнойВыгрузкойИНеЗапоминатьВыгруженные = Ложь
				ЗначениеСсылкиВДругойИБ,  // ЗначениеСсылкиВДругойИБ
				СписокВременныхФайлов,    // СписокВременныхФайлов = Неопределено
				ВыгрузкаСтрокиНабораЗаписейРегистра, // ВыгрузкаСтрокиНабораЗаписейРегистра = Ложь
				СтекВыгрузкиОбъекта);
				
			КонецЕсли;
			
		КонецЕсли;    
		
		// Обработчик ПослеВыгрузки
		
		Если ПКО.ЕстьОбработчикПослеВыгрузки Тогда
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКО_ПослеВыгрузкиОбъекта(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО, ПКО,
																 ВыгруженныеОбъекты, КлючВыгружаемыхДанных, Отказ, Приемник, УзелСсылки);
					
				Иначе
					
					Выполнить(ПКО.ПослеВыгрузки);
					
				КонецЕсли;
				
			Исключение
				ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(43, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
					ПКО, Источник, "ПослеВыгрузкиОбъекта");
			КонецПопытки;
			
			Если Отказ Тогда	//	Отказ от записи объекта в файл.
				
				Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
					СтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки);				
				КонецЕсли;
				
				ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
				Возврат УзелСсылки;
			КонецЕсли;
		КонецЕсли;
		
		
	//	Запись объекта в файл
	
	ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1;
	
	Если УзелПредка <> Неопределено Тогда
		
		Приемник.ЗаписатьКонецЭлемента();
		
		УзелПредка.ЗаписатьБезОбработки(Приемник.Закрыть());
		
	Иначе
	
		Если СписокВременныхФайлов = Неопределено Тогда
			
			Приемник.ЗаписатьКонецЭлемента();
			ЗаписатьВФайл(Приемник);
			
		Иначе
			
			ЗаписатьВФайл(Приемник);
		
			ВременныйФайл = Новый ЧтениеТекста;
			Для каждого ИмяВременногоФайла Из СписокВременныхФайлов Цикл
				
				Попытка
					ВременныйФайл.Открыть(ИмяВременногоФайла, КодировкаТекста.UTF8);
				Исключение
					Продолжить;
				КонецПопытки;
				
				СтрокаВременногоФайла = ВременныйФайл.ПрочитатьСтроку();
				Пока СтрокаВременногоФайла <> Неопределено Цикл
					ЗаписатьВФайл(СтрокаВременногоФайла);	
				    СтрокаВременногоФайла = ВременныйФайл.ПрочитатьСтроку();
				КонецЦикла;
				
				ВременныйФайл.Закрыть();
				
				// удалить файлы
				УдалитьФайлы(ИмяВременногоФайла); 
			КонецЦикла;
			
			ЗаписатьВФайл("</Объект>");
			
		КонецЕсли;
		
		Если НужноЗапоминатьОбъект
			И ЭтоПравилоСГлобальнойВыгрузкойОбъектов Тогда
				
			СтрокаВыгруженныхОбъектов.УзелСсылки = НПП;
			
		КонецЕсли;
		
		Если ТекущийУровеньВложенностиВыгрузитьПоПравилу = 0 Тогда
			
			ПровестиУстановкуПризнаковВыгруженныхОбъектовВФайл();
			
		КонецЕсли;
		
		ПровестиОбновлениеДанныхВВыгружаемыхДанных();		
		
	КонецЕсли;
	
	Если СтрокаВСтекеВыгрузки <> Неопределено Тогда
		СтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки);				
	КонецЕсли;
	
	// Обработчик ПослеВыгрузкиВФайл
	Если ПКО.ЕстьОбработчикПослеВыгрузкиВФайл Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПКО_ПослеВыгрузкиОбъектаВФайлОбмена(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные,
																		ИмяПКО, ПКО, ВыгруженныеОбъекты, Приемник, УзелСсылки);
				
			Иначе
				
				Выполнить(ПКО.ПослеВыгрузкиВФайл);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(79, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ПКО, Источник, "ЕстьОбработчикПослеВыгрузкиВФайл");
		КонецПопытки;
		
	КонецЕсли;
	
	Возврат УзелСсылки;
	
КонецФункции

// Выгружает регистр, вызывая правила ПередВыгрузкой и ПослеВыгрузки.
//
// Параметры:
//         НаборЗаписейДляВыгрузки - НаборЗаписейРегистра - также может быть Структура, содержащая отбор.
//         Правило - СтрокаТаблицыЗначений - таблицы правил конвертации объектов.
//         ВходящиеДанные - Произвольный - входящие данные для правила конвертации.
//         НеВыгружатьОбъектыСвойствПоСсылкам - Булево - признак для выгрузки свойств по ссылкам.
//         ИмяПКО - Строка - имя правила конвертации.
//
// Возвращаемое значение:
//         Булево - признак успешной выгрузки.
//
Функция ВыгрузкаРегистра(НаборЗаписейДляВыгрузки,
							Правило = Неопределено,
							ВходящиеДанные = Неопределено,
							НеВыгружатьОбъектыСвойствПоСсылкам = Ложь,
							ИмяПКО = "") Экспорт
							
	ИмяПКО			= "";
	Отказ			= Ложь;
	ИсходящиеДанные	= Неопределено;
		
	ВызватьСобытияПередВыгрузкойОбъекта(НаборЗаписейДляВыгрузки, Правило, Неопределено, ВходящиеДанные, 
		НеВыгружатьОбъектыСвойствПоСсылкам, ИмяПКО, Отказ, ИсходящиеДанные);
		
	Если Отказ Тогда
		Возврат Ложь;
	КонецЕсли;	
	
	
	ВыгрузитьРегистр(НаборЗаписейДляВыгрузки, 
					 Неопределено, 
					 ИсходящиеДанные, 
					 НеВыгружатьОбъектыСвойствПоСсылкам, 
					 ИмяПКО,
					 Правило);
		
	ВызватьСобытияПослеВыгрузкиОбъекта(НаборЗаписейДляВыгрузки, Правило, Неопределено, ВходящиеДанные, 
		НеВыгружатьОбъектыСвойствПоСсылкам, ИмяПКО, Отказ, ИсходящиеДанные);	
		
	Возврат Не Отказ;							
							
КонецФункции

// Формирует результат запроса для выгрузки очистки данных.
//
//  Параметры:
//       Свойства                      - Структура - содержащая свойства объекта.
//       ИмяТипа                       - Строка - имя типа объекта.
//       ВыборкаДляОчисткиДанных       - Булево - признак передачи выборки для очистки.
//       УдалятьОбъектыНепосредственно - Булево - признак необходимости непосредственного удаления.
//       ВыбиратьВсеПоля               - Булево - признак необходимости выбора всех полей.
//
//  Возвращаемое значение:
//       РезультатЗапроса, Неопределено - результат выполнения запроса для выгрузки очистки данных.
//
Функция РезультатЗапросаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, 
	ВыборкаДляОчисткиДанных = Ложь, УдалятьОбъектыНепосредственно = Ложь, ВыбиратьВсеПоля = Истина) Экспорт 
	
	СтрокаРазрешения = ?(ВыгружатьТолькоРазрешенные, " РАЗРЕШЕННЫЕ ", ""); // @Query-part-1
	
	СтрокаВыбораПолей = ?(ВыбиратьВсеПоля, " * ", "	ОбъектДляВыгрузки.Ссылка КАК Ссылка ");
	
	Если ИмяТипа = "Справочник" 
		ИЛИ ИмяТипа = "ПланВидовХарактеристик" 
		ИЛИ ИмяТипа = "ПланСчетов" 
		ИЛИ ИмяТипа = "ПланВидовРасчета" 
		ИЛИ ИмяТипа = "РегистрБухгалтерии"
		ИЛИ ИмяТипа = "ПланОбмена"
		ИЛИ ИмяТипа = "Задача"
		ИЛИ ИмяТипа = "БизнесПроцесс" Тогда
		
		Запрос = Новый Запрос;
		
		Запрос.Текст =
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	ОбъектДляВыгрузки.Ссылка КАК Ссылка
		|ИЗ
		|	&ИмяТаблицыМетаданных КАК ОбъектДляВыгрузки
		|ГДЕ ОбъектДляВыгрузки.Родитель = &Родитель";
		
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицыМетаданных", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1.%2", ИмяТипа, Свойства.Имя));
		
		Если НЕ ВыгружатьТолькоРазрешенные Тогда
			
			Запрос.Текст = СтрЗаменить(Запрос.Текст, "РАЗРЕШЕННЫЕ", ""); // @Query-part-1
			
		КонецЕсли;
		
		Если ВыбиратьВсеПоля 
			ИЛИ ИмяТипа = "РегистрБухгалтерии" Тогда
			
			Запрос.Текст = СтрЗаменить(Запрос.Текст, "ОбъектДляВыгрузки.Ссылка КАК Ссылка", "*");
			
		КонецЕсли;
		
		Если (ВыборкаДляОчисткиДанных И УдалятьОбъектыНепосредственно)
			И ((ИмяТипа = "Справочник" И Метаданные.Справочники[Свойства.Имя].Иерархический)
				ИЛИ (ИмяТипа = "ПланВидовХарактеристик" И Метаданные.ПланыВидовХарактеристик[Свойства.Имя].Иерархический)) Тогда
			
			Запрос.УстановитьПараметр("Родитель", Свойства.Менеджер.ПустаяСсылка());
			
		Иначе
			
			Запрос.Текст = СтрЗаменить(Запрос.Текст, "ГДЕ ОбъектДляВыгрузки.Родитель = &Родитель", "");
			
		КонецЕсли;
		
	ИначеЕсли ИмяТипа = "Документ" Тогда
		
		Запрос = Новый Запрос;
		
		Запрос.Текст =
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	ОбъектДляВыгрузки.Ссылка КАК Ссылка
		|ИЗ
		|	&ИмяТаблицыМетаданных КАК ОбъектДляВыгрузки";
		
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицыМетаданных", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1.%2", ИмяТипа, Свойства.Имя));
		
		Если НЕ ВыгружатьТолькоРазрешенные Тогда
			
			Запрос.Текст = СтрЗаменить(Запрос.Текст, "РАЗРЕШЕННЫЕ", ""); // @Query-part-1
			
		КонецЕсли;
		
	ИначеЕсли ИмяТипа = "РегистрСведений" Тогда
		
		Запрос = Новый Запрос;
		Запрос.Текст = 
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ
		| *
		| ,NULL КАК Активность
		| ,NULL КАК Регистратор
		| ,NULL КАК НомерСтроки
		| ,NULL КАК Период
		|ИЗ
		| &ИмяТаблицыМетаданных КАК ОбъектДляВыгрузки";
		
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицыМетаданных", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1.%2", ИмяТипа, Свойства.Имя));
		
		Если Свойства.ПодчиненныйРегистратору Тогда
			
			Запрос.Текст = СтрЗаменить(Запрос.Текст, ",NULL КАК Активность", "");
			Запрос.Текст = СтрЗаменить(Запрос.Текст, ",NULL КАК Регистратор", "");
			Запрос.Текст = СтрЗаменить(Запрос.Текст, ",NULL КАК НомерСтроки", "");
			
		КонецЕсли;
		
		Если Свойства.Периодический Тогда
			
			Запрос.Текст = СтрЗаменить(Запрос.Текст, ",NULL КАК Период", "");
			
		КонецЕсли;
		
	Иначе
		
		Возврат Неопределено;
		
	КонецЕсли;
	
	
	Возврат Запрос.Выполнить();
	
КонецФункции

// Формирует выборку для выгрузки очистки данных.
//
//  Параметры:
//       Свойства                      - Структура - содержащая свойства объекта.
//       ИмяТипа                       - Строка - имя типа объекта.
//       ВыборкаДляОчисткиДанных       - Булево - признак передачи выборки для очистки.
//       УдалятьОбъектыНепосредственно - Булево - признак необходимости непосредственного удаления.
//       ВыбиратьВсеПоля               - Булево - признак необходимости выбора всех полей.
//
//  Возвращаемое значение:
//       ВыборкаИзРезультатаЗапроса, Неопределено - сформированная выборка для очистки данных.
//
Функция ВыборкаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, 
	ВыборкаДляОчисткиДанных = Ложь, УдалятьОбъектыНепосредственно = Ложь, ВыбиратьВсеПоля = Истина) Экспорт
	
	РезультатЗапроса = РезультатЗапросаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, 
			ВыборкаДляОчисткиДанных, УдалятьОбъектыНепосредственно, ВыбиратьВсеПоля);
			
	Если РезультатЗапроса = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
			
	Выборка = РезультатЗапроса.Выбрать();
	
	
	Возврат Выборка;		
	
КонецФункции

// Выгружает данные по указанному правилу.
//
// Параметры:
//  Правило - СтрокаТаблицыЗначений - ссылка на правило выгрузки данных:
//     * Включить - Булево
//     * Имя - Произвольный
//     * Наименование - Произвольный
//     * Порядок - Произвольный
//     * СпособОтбораДанных - Произвольный
//     * ОбъектВыборки - Произвольный
//     * ОбъектВыборкиМетаданные - Произвольный
//     * ПравилоКонвертации - Произвольный
//     * ПередОбработкой - Произвольный
//     * ИмяОбработчикаПередОбработкой - Произвольный
//     * ПослеОбработки - Произвольный
//     * ИмяОбработчикаПослеОбработки - Произвольный
//     * ПередВыгрузкой - Произвольный
//     * ИмяОбработчикаПередВыгрузкой - Произвольный
//     * ПослеВыгрузки - Произвольный
//     * ИмяОбработчикаПослеВыгрузки - Произвольный
//     * ИспользоватьОтбор - Булево
//     * НастройкиПостроителя - Произвольный
//     * ИмяОбъектаДляЗапроса - Произвольный
//     * ИмяОбъектаДляЗапросаРегистра - Произвольный
//     * ИмяТипаПриемника - Произвольный
//     * НеВыгружатьОбъектыСозданныеВБазеПриемнике - Булево
//     * СсылкаНаУзелОбмена - Произвольный
//     * СинхронизироватьПоИдентификатору - Булево
// 
Процедура ВыгрузитьДанныеПоПравилу(Правило) Экспорт
	
	ИмяПКО = Правило.ПравилоКонвертации;
	
	Если Не ПустаяСтрока(ИмяПКО) Тогда
		
		ПКО = Правила[ИмяПКО];
		
	КонецЕсли;


	Если ФлагКомментироватьОбработкуОбъектов Тогда
		
		СтрокаСообщения = НСтр("ru = 'ПРАВИЛО ВЫГРУЗКИ ДАННЫХ: %1 (%2)'");
		СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, СокрЛП(Правило.Имя), СокрЛП(Правило.Наименование));
		ЗаписатьВПротоколВыполнения(СтрокаСообщения, , Ложь, , 4);
		
	КонецЕсли;
		
	
	// Обработчик ПередОбработкой
	Отказ           = Ложь;
	ИсходящиеДанные = Неопределено;
	ВыборкаДанных   = Неопределено;
	
	Если Не ПустаяСтрока(Правило.ПередОбработкой) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПВД_ПередОбработкойПравила(Отказ, ИмяПКО, Правило, ИсходящиеДанные, ВыборкаДанных);
				
			Иначе
				
				Выполнить(Правило.ПередОбработкой);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеОбработчикиПВД(31, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, "ПередОбработкойВыгрузкиДанных");
			
		КонецПопытки;
		
		Если Отказ Тогда
			
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;
	
	// Стандартная выборка с отбором.
	Если Правило.СпособОтбораДанных = "СтандартнаяВыборка" И Правило.ИспользоватьОтбор Тогда

		Выборка = ВыборкаДляВыгрузкиСОграничениями(Правило);
		
		Пока Выборка.Следующий() Цикл
			ВыгрузкаОбъектаВыборки(Выборка.Ссылка, Правило, , ИсходящиеДанные);
		КонецЦикла;

	// Стандартная выборка без отбора.
	ИначеЕсли (Правило.СпособОтбораДанных = "СтандартнаяВыборка") Тогда
		
		Свойства = Менеджеры(Правило.ОбъектВыборки);
		ИмяТипа  = Свойства.ИмяТипа;
		
		Если ИмяТипа = "Константы" Тогда
			
			ВыгрузитьНаборКонстант(Правило, Свойства, ИсходящиеДанные);
			
		Иначе
			
			ЭтоНеСсылочныйТип = ИмяТипа =  "РегистрСведений" 
				ИЛИ ИмяТипа = "РегистрБухгалтерии";
			
			
			Если ЭтоНеСсылочныйТип Тогда
					
				ВыбиратьВсеПоля = ОпределитьНужноВыбиратьВсеПоля(Правило);
				
			Иначе
				
				// получаем только ссылку
				ВыбиратьВсеПоля = Ложь;	
				
			КонецЕсли;	
				
			
			Выборка = ВыборкаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, , , ВыбиратьВсеПоля);
			
			Если Выборка = Неопределено Тогда
				Возврат;
			КонецЕсли;
			
			Пока Выборка.Следующий() Цикл
				
				Если ЭтоНеСсылочныйТип Тогда
					
					ВыгрузкаОбъектаВыборки(Выборка, Правило, Свойства, ИсходящиеДанные);
					
				Иначе
					
					ВыгрузкаОбъектаВыборки(Выборка.Ссылка, Правило, Свойства, ИсходящиеДанные);
					
				КонецЕсли;
				
			КонецЦикла;
			
		КонецЕсли;
		
	ИначеЕсли Правило.СпособОтбораДанных = "ПроизвольныйАлгоритм" Тогда

		Если ВыборкаДанных <> Неопределено Тогда
			
			Выборка = ВыборкаДляВыгрузкиПоПроизвольномуАлгоритму(ВыборкаДанных);
			
			Если Выборка <> Неопределено Тогда
				
				Пока Выборка.Следующий() Цикл
					
					ВыгрузкаОбъектаВыборки(Выборка, Правило, , ИсходящиеДанные);
					
				КонецЦикла;
				
			Иначе
				
				Для каждого Объект Из ВыборкаДанных Цикл
					
					ВыгрузкаОбъектаВыборки(Объект, Правило, , ИсходящиеДанные);
					
				КонецЦикла;
				
			КонецЕсли;
			
		КонецЕсли;
			
	КонецЕсли;

	
	// Обработчик ПослеОбработки
	
	Если Не ПустаяСтрока(Правило.ПослеОбработки) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПВД_ПослеОбработкиПравила(ИмяПКО, Правило, ИсходящиеДанные);
				
			Иначе
				
				Выполнить(Правило.ПослеОбработки);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеОбработчикиПВД(32, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, "ПослеОбработкиВыгрузкиДанных");
			
		КонецПопытки;
		
	КонецЕсли;
	
КонецПроцедуры

// Добавляет в xml файл информацию о типах значения.
//
// Параметры:
//   Приемник - ЗаписьXML - xml-узел объекта приемника.
//   Тип - Строка
//       - Массив из Строка - выгружаемый одиночный тип, или список выгружаемых строковых типов.
//   СписокАтрибутов - Структура - ключ содержит имя атрибута.
//
Процедура ВыгрузитьИнформациюОТипах(Приемник, Тип, СписокАтрибутов = Неопределено) Экспорт
	
	УзелТипов = СоздатьУзел("Типы");
	
	Если СписокАтрибутов <> Неопределено Тогда
		Для Каждого ЭлементКоллекции Из СписокАтрибутов Цикл
			УстановитьАтрибут(УзелТипов, ЭлементКоллекции.Ключ, ЭлементКоллекции.Значение);
		КонецЦикла;
	КонецЕсли;
	
	Если ТипЗнч(Тип) = Тип("Строка") Тогда
		одЗаписатьЭлемент(УзелТипов, "Тип", Тип);
	Иначе
		Для Каждого ТипСтрокой Из Тип Цикл
			одЗаписатьЭлемент(УзелТипов, "Тип", ТипСтрокой);
		КонецЦикла;
	КонецЕсли;
	
	ДобавитьПодчиненный(Приемник, УзелТипов);
	
КонецПроцедуры

// Создает в файле обмена запись об удалении объекта.
//
// Параметры:
//  Ссылка - СправочникСсылка
//         - ДокументСсылка - удаляемый объект.
//  ТипПриемника - Строка - содержит строковое представление типа приемника.
//  ТипИсточника - Строка - содержит строковое представление типа источника.
// 
Процедура ЗаписатьВФайлУдалениеОбъекта(Ссылка, Знач ТипПриемника, Знач ТипИсточника) Экспорт
	
	Приемник = СоздатьУзел("УдалениеОбъекта");
	
	УстановитьАтрибут(Приемник, "ТипПриемника", ТипПриемника);
	УстановитьАтрибут(Приемник, "ТипИсточника", ТипИсточника);
	
	УстановитьАтрибут(Приемник, "УникальныйИдентификатор", Ссылка.УникальныйИдентификатор());
	
	Приемник.ЗаписатьКонецЭлемента(); // УдалениеОбъекта
	
	ЗаписатьВФайл(Приемник);
	
КонецПроцедуры

// Регистрирует объект, созданный при выгрузке.
//
// Параметры:
//  Ссылка - СправочникСсылка
//         - ДокументСсылка - регистрируемый объект.
// 
Процедура ЗарегистрироватьОбъектСозданныйПриВыгрузке(Ссылка) Экспорт
	
	Если СозданныеПриВыгрузкеОбъекты().Найти(Ссылка) = Неопределено Тогда
		
		СозданныеПриВыгрузкеОбъекты().Добавить(Ссылка);
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ПолучениеДанных

// Возвращает таблицу значений, в которой содержатся ссылки на документы для отложенного проведения,
// а также даты этих документов для предварительной сортировки.
//
// Возвращаемое значение:
//  ТаблицаЗначений - содержит ссылки на документы для отложенного проведения. Колонки:
//    * ДокументСсылка - ДокументСсылка - ссылка на загруженный документ требующий отложенного проведения;
//    * ДатаДокумента  - Дата - дата загруженного документа для предварительной сортировки таблицы.
//
Функция ДокументыДляОтложенногоПроведения() Экспорт
	
	Если ТипЗнч(ПолеДокументыДляОтложенногоПроведения) <> Тип("ТаблицаЗначений") Тогда
		
		// Инициализируем таблицу для отложенного проведения документов.
		ПолеДокументыДляОтложенногоПроведения = Новый ТаблицаЗначений;
		ПолеДокументыДляОтложенногоПроведения.Колонки.Добавить("ДокументСсылка");
		ПолеДокументыДляОтложенногоПроведения.Колонки.Добавить("ДатаДокумента", одОписаниеТипа("Дата"));
		
	КонецЕсли;
	
	Возврат ПолеДокументыДляОтложенногоПроведения;
	
КонецФункции

// Признак того, что это загрузка в информационную базу.
// 
// Возвращаемое значение:
//  Булево - признак режима загрузки данных.
// 
Функция РежимЗагрузкиДанныхВИнформационнуюБазу() Экспорт
	
	Возврат ПустаяСтрока(РежимЗагрузкиДанных) ИЛИ ВРег(РежимЗагрузкиДанных) = ВРег("ЗагрузкаВИнформационнуюБазу");
	
КонецФункции

// Добавляет в таблицу отложенного проведения строку содержащую ссылку на документ,
// который необходимо провести и дату документа для предварительной сортировки.
//
// Параметры:
//  СсылкаНаОбъект         - ДокументСсылка - объект, который необходимо провести отложенно.
//  ДатаОбъекта            - Дата - дата документа;
//  ДополнительныеСвойства - Структура - дополнительные свойства записываемого объекта.
//
Процедура ДобавитьОбъектДляОтложенногоПроведения(СсылкаНаОбъект, ДатаОбъекта, ДополнительныеСвойства) Экспорт
	
	ТаблицаОтложенногоПроведения = ДокументыДляОтложенногоПроведения();
	НоваяСтрока = ТаблицаОтложенногоПроведения.Добавить();
	НоваяСтрока.ДокументСсылка = СсылкаНаОбъект;
	НоваяСтрока.ДатаДокумента  = ДатаОбъекта;
	
	ДополнительныеСвойстваДляОтложенногоПроведения().Вставить(СсылкаНаОбъект, ДополнительныеСвойства);
	
КонецПроцедуры

// Записывает объект в информационную базу.
//
// Параметры:
//  Объект - СправочникОбъект
//         - ДокументОбъект - записываемый объект.
//  Тип - Строка - тип объекта строкой.
//  ЗаписатьОбъект - Булево - признак того что объект был записан.
//  ОтправкаНазад - Булево - признак того что состояние элемента данных в этой информационной
//                           базе должно быть передано в информационную базу корреспондента.
// 
Процедура ЗаписатьОбъектВИБ(Объект, Тип, ЗаписатьОбъект = Ложь, Знач ОтправкаНазад = Ложь) Экспорт
	
	// В режиме загрузки в ТЗ объекты не записываем.
	Если РежимЗагрузкиДанныхВТаблицуЗначений() Тогда
		Возврат;
	КонецЕсли;
		
	Если ОбщегоНазначения.РазделениеВключено()
		И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		
		Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
			МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
			ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных(Объект.Метаданные().ПолноеИмя());
		Иначе
			ЭтоРазделенныйОбъектМетаданных = Ложь;
		КонецЕсли;
		
		Если Не ЭтоРазделенныйОбъектМетаданных Тогда 
		
			СтрокаСообщенияОбОшибке = НСтр("ru = 'Попытка изменения неразделенных данных (%1) в разделенном сеансе.'");
			СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщенияОбОшибке, Объект.Метаданные().ПолноеИмя());
			
			ЗаписатьВПротоколВыполнения(СтрокаСообщенияОбОшибке,, Ложь,,,, Перечисления.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями);
			
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;
	
	// Устанавливаем режим загрузки данных для объекта.
	УстановитьОбменДаннымиЗагрузка(Объект,, ОтправкаНазад);
	
	// Выполняем проверку на пометку удаления предопределенного элемента.
	СнятьПометкуУдаленияСПредопределенногоЭлемента(Объект, Тип);
	
	НачатьТранзакцию();
	Попытка
		
		// Записываем объект в транзакцию.
		Объект.Записать();
		
		СоответствияОбъектовИнформационныхБаз = Неопределено;
		Если Объект.ДополнительныеСвойства.Свойство("СоответствияОбъектовИнформационныхБаз", СоответствияОбъектовИнформационныхБаз)
			И СоответствияОбъектовИнформационныхБаз <> Неопределено Тогда
			
			СоответствияОбъектовИнформационныхБаз.УникальныйИдентификаторИсточника = Объект.Ссылка;
			
			РегистрыСведений.СоответствияОбъектовИнформационныхБаз.ДобавитьЗапись(СоответствияОбъектовИнформационныхБаз);
		КонецЕсли;
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		
		ЗаписатьОбъект = Ложь;
		
		СтрокаСообщенияОбОшибке = ЗаписатьИнформациюОбОшибкеВПротокол(26, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
			Объект, Тип);
		
		Если Не ПродолжитьПриОшибке Тогда
			ВызватьИсключение СтрокаСообщенияОбОшибке;
		КонецЕсли;
		
	КонецПопытки;
	
КонецПроцедуры

// Отменяет проведение объекта в информационной базе.
//
// Параметры:
//  Объект - ДокументОбъект - документ для отмены проведения.
//  Тип - Строка - тип объекта строкой.
//  ЗаписатьОбъект - Булево - признак того что объект был записан.
//
Процедура ОтменитьПроведениеОбъектаВИБ(Объект, Тип, ЗаписатьОбъект = Ложь) Экспорт
	
	Если ОбменДаннымиСобытия.ЗагрузкаЗапрещена(Объект, УзелОбменаЗагрузкаДанныхОбъект) Тогда
		Возврат;
	КонецЕсли;
	
	РегистрыСведений.РезультатыОбменаДанными.ЗарегистрироватьУстранениеПроблемы(Объект,
		Перечисления.ТипыПроблемОбменаДанными.НепроведенныйДокумент);
	
	// Устанавливаем режим загрузки данных для объекта.
	УстановитьОбменДаннымиЗагрузка(Объект);
	
	НачатьТранзакцию();
	Попытка
		
		// Отменяем проведение документа.
		Объект.Проведен = Ложь;
		Объект.Записать();
		
		СоответствияОбъектовИнформационныхБаз = Неопределено;
		Если Объект.ДополнительныеСвойства.Свойство("СоответствияОбъектовИнформационныхБаз", СоответствияОбъектовИнформационныхБаз)
			И СоответствияОбъектовИнформационныхБаз <> Неопределено Тогда
			
			СоответствияОбъектовИнформационныхБаз.УникальныйИдентификаторИсточника = Объект.Ссылка;
			
			РегистрыСведений.СоответствияОбъектовИнформационныхБаз.ДобавитьЗапись(СоответствияОбъектовИнформационныхБаз);
		КонецЕсли;
		
		ОбменДаннымиСервер.УдалитьДвиженияУДокумента(Объект);
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		
		ЗаписатьОбъект = Ложь;
		
		СтрокаСообщенияОбОшибке = ЗаписатьИнформациюОбОшибкеВПротокол(26, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
			Объект, Тип);
		
		Если Не ПродолжитьПриОшибке Тогда
			ВызватьИсключение СтрокаСообщенияОбОшибке;
		КонецЕсли;
		
	КонецПопытки;
	
КонецПроцедуры

// Устанавливает пометку удаления.
//
// Параметры:
//  Объект - СправочникОбъект
//         - ДокументОбъект - объект для установки пометки.
//  ПометкаУдаления - Булево - флаг пометки удаления.
//  ИмяТипаОбъекта - Строка - тип объекта строкой.
//
Процедура УстановитьПометкуУдаленияУОбъекта(Объект, ПометкаУдаления, ИмяТипаОбъекта) Экспорт
	
	Если (ПометкаУдаления = Неопределено И Объект.ПометкаУдаления <> Истина)
		Или ОбменДаннымиСобытия.ЗагрузкаЗапрещена(Объект, УзелОбменаЗагрузкаДанныхОбъект) Тогда
		Возврат;
	КонецЕсли;
	
	Если ИмяТипаОбъекта = "Документ" Тогда
		УстановитьОбменДаннымиЗагрузка(Объект, Ложь);
		РегистрыСведений.РезультатыОбменаДанными.ЗарегистрироватьУстранениеПроблемы(Объект,
			Перечисления.ТипыПроблемОбменаДанными.НепроведенныйДокумент);
	КонецЕсли;
	
	ПометкаДляУстановки = ?(ПометкаУдаления <> Неопределено, ПометкаУдаления, Ложь);
	
	УстановитьОбменДаннымиЗагрузка(Объект);
		
	// Дли иерархических объектов пометку удаления только у конкретного объекта ставим.
	Если ИмяТипаОбъекта = "Справочник"
		ИЛИ ИмяТипаОбъекта = "ПланВидовХарактеристик"
		ИЛИ ИмяТипаОбъекта = "ПланСчетов" Тогда
		
		Если Не Объект.Предопределенный Тогда
			
			Объект.УстановитьПометкуУдаления(ПометкаДляУстановки, Ложь);
			
		КонецЕсли;
		
	Иначе
		
		Объект.УстановитьПометкуУдаления(ПометкаДляУстановки);
		
	КонецЕсли;	
	
КонецПроцедуры

#КонецОбласти

#Область Прочее

// Регистрирует предупреждение в журнале регистрации.
// Если в процессе обмена данными было обращение к этой процедуре, то обмен данными остановлен не будет.
// После завершения обмена статус выполнения обмена в мониторе для пользователя будет иметь значение "Предупреждение",
// если не было ошибок.
//
// Параметры:
//  Предупреждение - Строка - текст предупреждения, который надо зарегистрировать.
//            Информация, предупреждения и ошибки, возникающие в процессе обмена данными регистрируются в журнале регистрации.
// 
Процедура ЗарегистрироватьПредупреждение(Предупреждение) Экспорт
	
	ЗаписатьВПротоколВыполнения(Предупреждение,,Ложь,,,, Перечисления.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями);
	
КонецПроцедуры

// Устанавливает состояние пометки у подчиненных строк строки дерева значений.
// В зависимости от пометки текущей строки.
//
// Параметры:
//  ТекСтрока - СтрокаДереваЗначений - у элементов которой следует установить пометки.
//  Реквизит - Строка - имя реквизита дерева который отвечает за пометку.
// 
Процедура УстановитьПометкиПодчиненных(ТекСтрока, Реквизит) Экспорт

	Подчиненные = ТекСтрока.Строки;

	Если Подчиненные.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Для Каждого Строка Из Подчиненные Цикл
		
		Если Строка.НастройкиПостроителя = Неопределено 
			И Реквизит = "ИспользоватьОтбор" Тогда
			
			Строка[Реквизит] = 0;
			
		Иначе
			
			Строка[Реквизит] = ТекСтрока[Реквизит];
			
		КонецЕсли;
		
		УстановитьПометкиПодчиненных(Строка, Реквизит);
		
	КонецЦикла;
		
КонецПроцедуры

#КонецОбласти

#Область УстаревшиеПроцедурыИФункции

// Устарела: Следует использовать функцию РезультатЗапросаДляВыгрузкиОчисткиДанных
// Формирует результат запроса для выгрузки очистки данных.
//
//  Параметры:
//       Свойства                      - Структура - содержащая свойства объекта.
//       ИмяТипа                       - Строка - имя типа объекта.
//       ВыборкаДляОчисткиДанных       - Булево - признак передачи выборки для очистки.
//       УдалятьОбъектыНепосредственно - Булево - признак необходимости непосредственного удаления.
//       ВыбиратьВсеПоля               - Булево - признак необходимости выбора всех полей.
//
//  Возвращаемое значение:
//       РезультатЗапроса, Неопределено - результат выполнения запроса для выгрузки очистки данных.
//
Функция ПолучитьРезультатЗапросаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, 
	ВыборкаДляОчисткиДанных = Ложь, УдалятьОбъектыНепосредственно = Ложь, ВыбиратьВсеПоля = Истина) Экспорт 
	
	Возврат РезультатЗапросаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа,
		ВыборкаДляОчисткиДанных, УдалятьОбъектыНепосредственно, ВыбиратьВсеПоля);
	
КонецФункции

// Устарела: Следует использовать функцию ВыборкаДляВыгрузкиОчисткиДанных
// Формирует выборку для выгрузки очистки данных.
//
//  Параметры:
//       Свойства                      - Структура - содержащая свойства объекта.
//       ИмяТипа                       - Строка - имя типа объекта.
//       ВыборкаДляОчисткиДанных       - Булево - признак передачи выборки для очистки.
//       УдалятьОбъектыНепосредственно - Булево - признак необходимости непосредственного удаления.
//       ВыбиратьВсеПоля               - Булево - признак необходимости выбора всех полей.
//
//  Возвращаемое значение:
//       ВыборкаИзРезультатаЗапроса, Неопределено - сформированная выборка для очистки данных.
//
Функция ПолучитьВыборкуДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, 
	ВыборкаДляОчисткиДанных = Ложь, УдалятьОбъектыНепосредственно = Ложь, ВыбиратьВсеПоля = Истина) Экспорт
	
	Возврат ВыборкаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа,
		ВыборкаДляОчисткиДанных, УдалятьОбъектыНепосредственно, ВыбиратьВсеПоля);
	
КонецФункции

#КонецОбласти

#КонецОбласти

#Область СлужебныйПрограммныйИнтерфейс

#Область ЭкспортныеСвойства

// Функция-свойство: флаг ошибки выполнения обмена данными.
//
// Возвращаемое значение:
//  Булево - флаг ошибки выполнения обмена данными.
//
Функция ФлагОшибки() Экспорт
	
	Если ТипЗнч(ПолеФлагОшибки) <> Тип("Булево") Тогда
		
		ПолеФлагОшибки = Ложь;
		
	КонецЕсли;
	
	Возврат ПолеФлагОшибки;
	
КонецФункции

// Функция-свойство: результат выполнения обмена данными.
//
// Возвращаемое значение:
//  ПеречислениеСсылка.РезультатыВыполненияОбмена - результат выполнения обмена данными.
//
Функция РезультатВыполненияОбмена() Экспорт
	
	Если ТипЗнч(ПолеРезультатВыполненияОбмена) <> Тип("ПеречислениеСсылка.РезультатыВыполненияОбмена") Тогда
		
		ПолеРезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Выполнено;
		
	КонецЕсли;
	
	Возврат ПолеРезультатВыполненияОбмена;
	
КонецФункции

// Функция-свойство: результат выполнения обмена данными.
//
// Возвращаемое значение:
//  Строка - строковое представление значения перечисления ПеречислениеСсылка.РезультатыВыполненияОбмена.
//
Функция РезультатВыполненияОбменаСтрокой() Экспорт
	
	Возврат ОбщегоНазначения.ИмяЗначенияПеречисления(РезультатВыполненияОбмена());
	
КонецФункции

// Функция-свойство: соответствие с таблицами данных входящего сообщения обмена.
//
// Возвращаемое значение:
//  Соответствие - соответствие с таблицами данных входящего сообщения обмена.
//
Функция ТаблицыДанныхСообщенияОбмена() Экспорт
	
	Если ТипЗнч(ПолеТаблицыДанныхСообщенияОбмена) <> Тип("Соответствие") Тогда
		
		ПолеТаблицыДанныхСообщенияОбмена = Новый Соответствие;
		
	КонецЕсли;
	
	Возврат ПолеТаблицыДанныхСообщенияОбмена;
	
КонецФункции

// Функция-свойство: таблица значений со статистической и дополнительной информацией о входящем сообщении обмена.
//
// Возвращаемое значение:
//  ТаблицаЗначений - таблица значений со статистической и дополнительной информацией о входящем сообщении обмена.
//
Функция ТаблицаДанныхЗаголовкаПакета() Экспорт
	
	Если ТипЗнч(ПолеТаблицаДанныхЗаголовкаПакета) <> Тип("ТаблицаЗначений") Тогда
		
		ПолеТаблицаДанныхЗаголовкаПакета = Новый ТаблицаЗначений;
		
		Колонки = ПолеТаблицаДанныхЗаголовкаПакета.Колонки;
		
		Колонки.Добавить("ТипОбъектаСтрокой",            одОписаниеТипа("Строка"));
		Колонки.Добавить("КоличествоОбъектовВИсточнике", одОписаниеТипа("Число"));
		Колонки.Добавить("ПоляПоиска",                   одОписаниеТипа("Строка"));
		Колонки.Добавить("ПоляТаблицы",                  одОписаниеТипа("Строка"));
		
		Колонки.Добавить("ТипИсточникаСтрокой", одОписаниеТипа("Строка"));
		Колонки.Добавить("ТипПриемникаСтрокой", одОписаниеТипа("Строка"));
		
		Колонки.Добавить("СинхронизироватьПоИдентификатору", одОписаниеТипа("Булево"));
		Колонки.Добавить("ЭтоУдалениеОбъекта", одОписаниеТипа("Булево"));
		Колонки.Добавить("ЭтоКлассификатор", одОписаниеТипа("Булево"));
		Колонки.Добавить("ИспользоватьПредварительныйПросмотр", одОписаниеТипа("Булево"));
		
	КонецЕсли;
	
	Возврат ПолеТаблицаДанныхЗаголовкаПакета;
	
КонецФункции

// Функция-свойство: строка, которая содержит сообщение об ошибке при обмене данными.
//
// Возвращаемое значение:
//  Строка - строка, которая содержит сообщение об ошибке при обмене данными.
//
Функция СтрокаСообщенияОбОшибке() Экспорт
	
	Если ТипЗнч(ПолеСтрокаСообщенияОбОшибке) <> Тип("Строка") Тогда
		
		ПолеСтрокаСообщенияОбОшибке = "";
		
	КонецЕсли;
	
	Возврат ПолеСтрокаСообщенияОбОшибке;
	
КонецФункции

// Функция-свойство: количество объектов, которые были загружены.
//
// Возвращаемое значение:
//  Число - количество объектов, которые были загружены.
//
Функция СчетчикЗагруженныхОбъектов() Экспорт
	
	Если ТипЗнч(ПолеСчетчикЗагруженныхОбъектов) <> Тип("Число") Тогда
		
		ПолеСчетчикЗагруженныхОбъектов = 0;
		
	КонецЕсли;
	
	Возврат ПолеСчетчикЗагруженныхОбъектов;
	
КонецФункции

// Функция-свойство: количество объектов, которые были выгружены.
//
// Возвращаемое значение:
//  Число - количество объектов, которые были выгружены.
//
Функция СчетчикВыгруженныхОбъектов() Экспорт
	
	Если ТипЗнч(ПолеСчетчикВыгруженныхОбъектов) <> Тип("Число") Тогда
		
		ПолеСчетчикВыгруженныхОбъектов = 0;
		
	КонецЕсли;
	
	Возврат ПолеСчетчикВыгруженныхОбъектов;
	
КонецФункции

#КонецОбласти

#Область ВыгрузкаДанных

// Выполняет выгрузку данных.
// -- Все объекты выгружаются в один файл.
// -- В заголовок файла выгружаются:
//	 - правила обмена.
//	 - информация о типах данных.
//	 - данные по обмену (имя плана обмена, коды узлов, номера сообщений (квитирование)).
//
// Параметры:
//      ОбработкаДляЗагрузкиДанных - ОбработкаОбъект.КонвертацияОбъектовИнформационныхБаз в COM-соединении.
//
Процедура ВыполнитьВыгрузкуДанных(ОбработкаДляЗагрузкиДанных = Неопределено) Экспорт
	
	ОбменДаннымиСервер.ОчиститьСписокОшибокПриВыгрузкеДанных(УзелДляОбмена);
	
	УстановитьФлагОшибки(Ложь);
	
	ПолеСтрокаСообщенияОбОшибке = "";
	ПолеСостояниеОбменаДанными = Неопределено;
	ПолеРезультатВыполненияОбмена = Неопределено;
	ПолеВыгруженныеПоСсылкеОбъекты = Неопределено;
	ПолеСозданныеПриВыгрузкеОбъекты = Неопределено;
	ПолеВыгружаемыеПоСсылкеОбъектыМетаданных = Неопределено;
	ПолеПравилаРегистрацииОбъектов = Неопределено;
	ПолеСвойстваУзлаПланаОбмена = Неопределено;
	ПолеОбработкаДляЗагрузкиДанных = ОбработкаДляЗагрузкиДанных;
	
	ИнициализироватьВедениеПротоколаОбмена();
	
	// Открываем файл обмена
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		ФайлОбмена = Новый ЗаписьТекста;
	Иначе
		
		Если ЭтоЗагрузкаСообщенияДляСопоставления() Тогда
			ИмяФайлаОбмена = ПолучитьИмяВременногоФайла("xml");
		КонецЕсли;
		
		ОткрытьФайлВыгрузки();
	КонецЕсли;
	
	Если ФлагОшибки() Тогда
		ФайлОбмена = Неопределено;
		ЗавершитьВедениеПротоколаОбмена();
		Возврат;
	КонецЕсли;
	
	ИмяПрофиляБезопасности = ИнициализироватьОбработки();
	
	Если ИмяПрофиляБезопасности <> Неопределено Тогда
		УстановитьБезопасныйРежим(ИмяПрофиляБезопасности);
	КонецЕсли;
	
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		
		ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеПередЗагрузкойДанных();
		
		ОбработкаДляЗагрузкиДанных().ЗагрузитьПравилаОбмена(XMLПравила, "Строка");
		
		Если ОбработкаДляЗагрузкиДанных().ФлагОшибки() Тогда
			
			СтрокаСообщения = НСтр("ru = 'Ошибка в базе-корреспонденте: %1'");
			СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ОбработкаДляЗагрузкиДанных().СтрокаСообщенияОбОшибке());
			ЗаписатьВПротоколВыполнения(СтрокаСообщения);
			ЗавершитьВедениеПротоколаОбмена();
			Возврат;
			
		КонецЕсли;
		
		Отказ = Ложь;
		
		ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеОбработчикКонвертацииПередЗагрузкойДанных(Отказ);
		
		Если Отказ Тогда
			ЗавершитьВедениеПротоколаОбмена();
			ОтключитьОбработкуДляОтладки();
			Возврат;
		КонецЕсли;
		
	Иначе
		
		// Включаем правила обмена в файл.
		ФайлОбмена.ЗаписатьСтроку(XMLПравила);
		
	КонецЕсли;
	
	// ВЫГРУЗКА ДАННЫХ
	Попытка
		ВыполнитьВыгрузку();
	Исключение
		ЗаписатьВПротоколВыполнения(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ЗавершитьВедениеПротоколаОбмена();
		ФайлОбмена = Неопределено;
		ПолеВыгруженныеПоСсылкеОбъекты = Неопределено;
		ПолеСозданныеПриВыгрузкеОбъекты = Неопределено;
		ПолеВыгружаемыеПоСсылкеОбъектыМетаданных = Неопределено;
		Возврат;
	КонецПопытки;
	
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		
		Если Не ФлагОшибки() Тогда
			
			ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеПослеЗагрузкиДанных();
			
		КонецЕсли;
		
	Иначе
		
		// Закрываем файл обмена
		ЗакрытьФайл();
		
	КонецЕсли;
	
	ЗавершитьВедениеПротоколаОбмена();
	
	Если ЭтоЗагрузкаСообщенияДляСопоставления() Тогда
		
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.Прочитать(ИмяФайлаОбмена);
		
		ОбработкаДляЗагрузкиДанных().ПоместитьСообщениеДляСопоставленияДанных(ТекстовыйДокумент.ПолучитьТекст());
		
		ТекстовыйДокумент = Неопределено;
		
		УдалитьФайлы(ИмяФайлаОбмена);
		
	КонецЕсли;
	
	// Сбрасываем модальные переменные перед помещением обработки в платформенный кэш.
	ПолеВыгруженныеПоСсылкеОбъекты = Неопределено;
	ПолеСозданныеПриВыгрузкеОбъекты = Неопределено;
	ПолеВыгружаемыеПоСсылкеОбъектыМетаданных = Неопределено;
	ОтключитьОбработкуДляОтладки();
	ФайлОбмена = Неопределено;
	
КонецПроцедуры

// Выгружает регистр по отбору.
// 
// Параметры:
//         НаборЗаписейДляВыгрузки - Структура - содержащая отбор, или НаборЗаписей регистра.
//         Правило - СтрокаТаблицыЗначений - из правил конвертации объектов:
//           * Свойства - см. КоллекцияПравилаКонвертацииСвойств
//         ВходящиеДанные - Произвольный - входящие данные для правила конвертации.
//         НеВыгружатьОбъектыПоСсылкам - Булево - признак для выгрузки свойств по ссылкам..
//         ИмяПКО - Строка - имя правила конвертации.
//         ПравилоВыгрузкиДанных - СтрокаТаблицыЗначений - из таблицы правил выгрузки данных.
//
Процедура ВыгрузитьРегистр(НаборЗаписейДляВыгрузки, 
							Правило = Неопределено, 
							ВходящиеДанные = Неопределено, 
							НеВыгружатьОбъектыПоСсылкам = Ложь, 
							ИмяПКО = "",
							ПравилоВыгрузкиДанных = Неопределено) Экспорт
							
	ИсходящиеДанные = Неопределено;						
							
	
	ОпределитьПКОПоПараметрам(Правило, НаборЗаписейДляВыгрузки, ИмяПКО);
	
	ПриоритетОбъектовОбмена = Правило.ПриоритетОбъектовОбмена;
	
	Если ТипЗнч(НаборЗаписейДляВыгрузки) = Тип("Структура") Тогда
		
		ОтборНабораЗаписей  = НаборЗаписейДляВыгрузки.Отбор;
		СтрокиНабораЗаписей = НаборЗаписейДляВыгрузки.Строки;
		
	Иначе // НаборЗаписей
		
		ОтборНабораЗаписей  = НаборЗаписейДляВыгрузки.Отбор;
		СтрокиНабораЗаписей = НаборЗаписейДляВыгрузки;
		
	КонецЕсли;
	
	// Записываем сначала отбор потом набор записей
	// отбор.
	
	Приемник = СоздатьУзел("НаборЗаписейРегистра");
	
	КоличествоЗаписейВРегистре = СтрокиНабораЗаписей.Количество();
		
	СчетчикНПП = СчетчикНПП + 1;
	НПП        = СчетчикНПП;
	
	УстановитьАтрибут(Приемник, "Нпп",			НПП);
	УстановитьАтрибут(Приемник, "Тип", 			СтрЗаменить(Правило.Приемник, "РегистрСведенийЗапись.", "РегистрСведенийНаборЗаписей."));
	УстановитьАтрибут(Приемник, "ИмяПравила",	Правило.Имя);
	
	ЗаписатьПриоритетОбъектовОбмена(ПриоритетОбъектовОбмена, Приемник);
	
	ВыгружаемПустойНабор = КоличествоЗаписейВРегистре = 0;
	Если ВыгружаемПустойНабор Тогда
		УстановитьАтрибут(Приемник, "ПустойНабор",	Истина);
	КонецЕсли;
	
	Приемник.ЗаписатьНачалоЭлемента("Отбор");
	
	СтруктураИсточник = Новый Структура;
	МассивПКСДляВыгрузки = Новый Массив();
	
	Для Каждого СтрокаОтбора Из ОтборНабораЗаписей Цикл
		
		Если СтрокаОтбора.Использование = Ложь Тогда
			Продолжить;
		КонецЕсли;
		
		СтрокаПКС = Правило.Свойства.Найти(СтрокаОтбора.Имя, "Источник");
		
		Если СтрокаПКС = Неопределено Тогда
			
			СтрокаПКС = Правило.Свойства.Найти(СтрокаОтбора.Имя, "Приемник");
			
		КонецЕсли;
		
		Если СтрокаПКС <> Неопределено
			И  (СтрокаПКС.ВидПриемника = "Свойство"
			ИЛИ СтрокаПКС.ВидПриемника = "Измерение") Тогда
			
			МассивПКСДляВыгрузки.Добавить(СтрокаПКС);
			
			Ключ = ?(ПустаяСтрока(СтрокаПКС.Источник), СтрокаПКС.Приемник, СтрокаПКС.Источник);
			
			СтруктураИсточник.Вставить(Ключ, СтрокаОтбора.Значение);
			
		КонецЕсли;
		
	КонецЦикла;
	
	// Добавляем параметры для отбора.
	Для Каждого СтрокаСвойстваПоиска Из Правило.СвойстваПоиска Цикл
		
		Если ПустаяСтрока(СтрокаСвойстваПоиска.Приемник)
			И НЕ ПустаяСтрока(СтрокаСвойстваПоиска.ИмяПараметраДляПередачи) Тогда
			
			МассивПКСДляВыгрузки.Добавить(СтрокаСвойстваПоиска);	
			
		КонецЕсли;
		
	КонецЦикла;
	
	ВыгрузитьСвойства(СтруктураИсточник, Неопределено, ВходящиеДанные, ИсходящиеДанные, Правило, МассивПКСДляВыгрузки, Приемник, 
		, , Истина, , , , ВыгружаемПустойНабор);
	
	Приемник.ЗаписатьКонецЭлемента();
	
	Приемник.ЗаписатьНачалоЭлемента("СтрокиНабораЗаписей");
	
	// Набор записей ВходящиеДанные = Неопределено;
	Для Каждого СтрокаРегистра Из СтрокиНабораЗаписей Цикл
		
		ВыгрузкаОбъектаВыборки(СтрокаРегистра, ПравилоВыгрузкиДанных, , ВходящиеДанные, НеВыгружатьОбъектыПоСсылкам, Истина, 
			Приемник, , ИмяПКО, ЛОЖЬ);
				
	КонецЦикла;
	
	Приемник.ЗаписатьКонецЭлемента();
	
	Приемник.ЗаписатьКонецЭлемента();
	
	ЗаписатьВФайл(Приемник);
	
	ПровестиОбновлениеДанныхВВыгружаемыхДанных();
	
	ПровестиУстановкуПризнаковВыгруженныхОбъектовВФайл();
	
КонецПроцедуры
#КонецОбласти

#Область ЗагрузкаДанных

// Выполняет загрузку данных из файла сообщения обмена.
// Данные загружаются в информационную базу.
//
// Параметры:
// 
Процедура ВыполнитьЗагрузкуДанных() Экспорт
	
	ОбменДаннымиСервер.ОчиститьСписокОшибокПриЗагрузкеДанных(УзелДляОбмена);
	
	Если ЗначениеЗаполнено(УзелОбменаЗагрузкаДанных) Тогда
		УзелОбменаЗагрузкаДанныхОбъект = УзелОбменаЗагрузкаДанных.ПолучитьОбъект();
	КонецЕсли;
	
	ЧтениеСообщения = Неопределено; // см. ОписаниеЧтенияСообщения
	Попытка
		РежимЗагрузкиДанных = "ЗагрузкаВИнформационнуюБазу";
		
		ПолеСтрокаСообщенияОбОшибке = "";
		ПолеСостояниеОбменаДанными = Неопределено;
		ПолеРезультатВыполненияОбмена = Неопределено;
		ПолеСоответствиеТиповДанныхДляЗагрузки = Неопределено;
		ПолеСчетчикЗагруженныхОбъектов = Неопределено;
		ПолеДокументыДляОтложенногоПроведения = Неопределено;
		ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
		СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
		ПолеСвойстваУзлаПланаОбмена = Неопределено;
		ПолеВерсияФорматаВходящегоСообщенияОбмена = Неопределено;
		ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Ложь;
		ЕстьИнформацияОРегистрацииОбъекта = Ложь;
		
		ГлобальныйСтекНеЗаписанныхОбъектов = Новый Соответствие;
		НомерПоследнегоПоискаПоСсылке = 0;
		
		ИнициализироватьМенеджерыИСообщения();
		
		УстановитьФлагОшибки(Ложь);
		
		ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных();
		
		ИнициализироватьВедениеПротоколаОбмена();
		
		ИнформацияОПользовательскихПоляхПоискаПриЗагрузкеДанных = Новый Соответствие;
		
		СоответствиеДопПараметровПоиска = Новый Соответствие;
		СоответствиеПравилКонвертации = Новый Соответствие;
		
		КоличествоВыполненныхОтложенныхДвиженийДокументов = 0;
		
		Если ПродолжитьПриОшибке Тогда
			ИспользоватьТранзакции = Ложь;
		КонецЕсли;
		
		Если КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 0 Тогда
			КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 100;
		КонецЕсли;
		
		РезультатАнализаДанныхКЗагрузке = ОбменДаннымиСервер.РезультатАнализаДанныхКЗагрузке(ИмяФайлаОбмена, Ложь);
		РазмерФайлаСообщенияОбмена = РезультатАнализаДанныхКЗагрузке.РазмерФайлаСообщенияОбмена;
		КоличествоОбъектовКЗагрузке = РезультатАнализаДанныхКЗагрузке.КоличествоОбъектовКЗагрузке;
		
		ИмяПрофиляБезопасности = ИнициализироватьОбработки();
		
		Если ИмяПрофиляБезопасности <> Неопределено Тогда
			УстановитьБезопасныйРежим(ИмяПрофиляБезопасности);
		КонецЕсли;
		
		НачатьЧтениеСообщения(ЧтениеСообщения);
		
		ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Истина);
		Если ИспользоватьТранзакции Тогда
			НачатьТранзакцию();
		КонецЕсли;
		Попытка
			
			ПроизвестиЧтениеДанных(ЧтениеСообщения);
			
			Если ФлагОшибки() Тогда
				ВызватьИсключение НСтр("ru = 'Возникли ошибки при загрузке данных.'");
			КонецЕсли;
			
			// Отложенная запись того, что не записали.
			ПровестиЗаписьНеЗаписанныхОбъектов();
			
			ВыполнитьОбработчикПослеЗагрузкиДанных();
			
			Если ФлагОшибки() Тогда
				ВызватьИсключение НСтр("ru = 'Возникли ошибки при загрузке данных.'");
			КонецЕсли;
			
			ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
			Если ИспользоватьТранзакции Тогда
				ЗафиксироватьТранзакцию();
			КонецЕсли;
		Исключение
			Если ИспользоватьТранзакции Тогда
				ОтменитьТранзакцию();
				ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь, Ложь);
			Иначе
				ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
			КонецЕсли;
			
			ПрерватьЧтениеСообщения(ЧтениеСообщения);
			ВызватьИсключение;
		КонецПопытки;
		
		// Выполняем проведение документов в очереди.
		ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Истина);
		Попытка
			ВыполнитьОтложенноеПроведениеДокументов();
			ВыполнитьОтложеннуюЗаписьОбъектов();
			
			ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
		Исключение
			ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
			ВызватьИсключение;
		КонецПопытки;
		
		ЗакончитьЧтениеСообщения(ЧтениеСообщения);
	Исключение
		Если ЧтениеСообщения <> Неопределено
			И ЧтениеСообщения.СообщениеБылоПринятоРанее Тогда
			ЗаписатьВПротоколВыполнения(174,,,,,,
				Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято);
		Иначе
			ЗаписатьВПротоколВыполнения(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецЕсли;
	КонецПопытки;
	
	ЗавершитьВедениеПротоколаОбмена();
	
	// Сбрасываем модальные переменные перед помещением обработки в платформенный кэш.
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСоответствиеТиповДанныхДляЗагрузки = Неопределено;
	ГлобальныйСтекНеЗаписанныхОбъектов = Неопределено;
	СоответствиеПравилКонвертации = Неопределено;
	ОтключитьОбработкуДляОтладки();
	ФайлОбмена = Неопределено;
	
КонецПроцедуры

#КонецОбласти

#Область ЗагрузкаДанныхПакетная

// Выполняет загрузку данных из файла сообщения обмена в Информационную Базу только заданных типов объектов.
//
// Параметры:
//  ТаблицыДляЗагрузки - Массив - массив типов, которые необходимо загрузить из сообщения обмена; элемент массива -
//                                Строка.
//  Например, для загрузки из сообщения обмена только элементов справочника Контрагенты:
//   ТаблицыДляЗагрузки = Новый Массив;
//   ТаблицыДляЗагрузки.Добавить("СправочникСсылка.Контрагенты");
// 
//  Список всех типов, которые содержаться в текущем сообщении обмена
//  можно получить вызовом процедуры ВыполнитьАнализСообщенияОбмена().
// 
Процедура ВыполнитьЗагрузкуДанныхВИнформационнуюБазу(ТаблицыДляЗагрузки) Экспорт
	
	Если ЗначениеЗаполнено(УзелОбменаЗагрузкаДанных) Тогда
		УзелОбменаЗагрузкаДанныхОбъект = УзелОбменаЗагрузкаДанных.ПолучитьОбъект();
	КонецЕсли;
	
	РежимЗагрузкиДанных = "ЗагрузкаВИнформационнуюБазу";
	ПолеСостояниеОбменаДанными = Неопределено;
	ПолеРезультатВыполненияОбмена = Неопределено;
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСвойстваУзлаПланаОбмена = Неопределено;
	ПолеВерсияФорматаВходящегоСообщенияОбмена = Неопределено;
	ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Ложь;
	ЕстьИнформацияОРегистрацииОбъекта = Ложь;
	ГлобальныйСтекНеЗаписанныхОбъектов = Новый Соответствие;
	СоответствиеПравилКонвертации = Новый Соответствие;
	
	// дата начала загрузки
	СостояниеОбменаДанными().ДатаНачала = ТекущаяДатаСеанса();
	
	// Запись в журнале регистрации.
	СтрокаСообщения = НСтр("ru = 'Начало процесса обмена данными для узла: %1'", ОбщегоНазначения.КодОсновногоЯзыка());
	СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, Строка(УзелОбменаЗагрузкаДанных));
	ЗаписьЖурналаРегистрацииОбменДанными(СтрокаСообщения, УровеньЖурналаРегистрации.Информация);
	
	ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Истина);
	Попытка
		ВыполнитьВыборочноеЧтениеСообщения(ТаблицыДляЗагрузки);
		ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
	Исключение
		ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
		ВызватьИсключение;
	КонецПопытки;
	
	// дата окончания загрузки
	СостояниеОбменаДанными().ДатаОкончания = ТекущаяДатаСеанса();
	
	// Фиксируем завершение загрузки данных в РС.
	ЗафиксироватьЗавершениеЗагрузкиДанных();
	
	// Запись в журнале регистрации.
	СтрокаСообщения = НСтр("ru = 'Выполняемое действие: %1;
		|Статус завершения: %2;
		|Обработано объектов: %3.'",
		ОбщегоНазначения.КодОсновногоЯзыка());
	СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения,
					РезультатВыполненияОбмена(),
					Перечисления.ДействияПриОбмене.ЗагрузкаДанных,
					Формат(СчетчикЗагруженныхОбъектов(), "ЧГ=0"));
	//
	ЗаписьЖурналаРегистрацииОбменДанными(СтрокаСообщения, УровеньЖурналаРегистрации.Информация);
	
	// Сбрасываем модальные переменные перед помещением обработки в платформенный кэш.
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСоответствиеТиповДанныхДляЗагрузки = Неопределено;
	ГлобальныйСтекНеЗаписанныхОбъектов = Неопределено;
	СоответствиеПравилКонвертации = Неопределено;
	ФайлОбмена = Неопределено;
	
КонецПроцедуры

// Выполняет загрузку данных из файла сообщения обмена в Таблицу значений только заданных типов объектов.
//
// Параметры:
//  ТаблицыДляЗагрузки - Массив - массив типов, которые необходимо загрузить из сообщения обмена; элемент массива -
//                                Строка.
//  Например, для загрузки из сообщения обмена только элементов справочника Контрагенты:
//   ТаблицыДляЗагрузки = Новый Массив;
//   ТаблицыДляЗагрузки.Добавить("СправочникСсылка.Контрагенты");
// 
//  Список всех типов, которые содержаться в текущем сообщении обмена
//  можно получить вызовом процедуры ВыполнитьАнализСообщенияОбмена().
// 
Процедура ВыполнитьЗагрузкуДанныхВТаблицуЗначений(ТаблицыДляЗагрузки) Экспорт
	
	Если ЗначениеЗаполнено(УзелОбменаЗагрузкаДанных) Тогда
		УзелОбменаЗагрузкаДанныхОбъект = УзелОбменаЗагрузкаДанных.ПолучитьОбъект();
	КонецЕсли;
	
	РежимЗагрузкиДанных = "ЗагрузкаВТаблицуЗначений";
	ПолеСостояниеОбменаДанными = Неопределено;
	ПолеРезультатВыполненияОбмена = Неопределено;
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСвойстваУзлаПланаОбмена = Неопределено;
	ПолеВерсияФорматаВходящегоСообщенияОбмена = Неопределено;
	ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Ложь;
	ЕстьИнформацияОРегистрацииОбъекта = Ложь;
	ГлобальныйСтекНеЗаписанныхОбъектов = Новый Соответствие;
	СоответствиеПравилКонвертации = Новый Соответствие;
	
	ИспользоватьТранзакции = Ложь;
	
	// Инициализируем таблицы данных сообщения обмена.
	Для Каждого КлючТаблицыДанных Из ТаблицыДляЗагрузки Цикл
		
		МассивПодстрок = СтрРазделить(КлючТаблицыДанных, "#");
		
		ТипОбъекта = МассивПодстрок[1];
		
		ТаблицыДанныхСообщенияОбмена().Вставить(КлючТаблицыДанных, ИнициализацияТаблицыДанныхСообщенияОбмена(Тип(ТипОбъекта)));
		
	КонецЦикла;
	
	ВыполнитьВыборочноеЧтениеСообщения(ТаблицыДляЗагрузки);
	
	// Сбрасываем модальные переменные перед помещением обработки в платформенный кэш.
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСоответствиеТиповДанныхДляЗагрузки = Неопределено;
	ГлобальныйСтекНеЗаписанныхОбъектов = Неопределено;
	СоответствиеПравилКонвертации = Неопределено;
	ФайлОбмена = Неопределено;
	
КонецПроцедуры

// Выполняет последовательное чтение файла сообщения обмена при этом:
//     - удаляется регистрация изменений по номеру входящей квитанции
//     - загружаются правила обмена
//     - загружается информация о типах данных
//     - зачитывается информация сопоставления данных и записывается и ИБ
//     - собирается информация о типах объектов и их количестве.
//
// Параметры:
//   ПараметрыАнализа - Структура - необязательные дополнительные параметры анализа. Допустимые поля:
//     * СобиратьСтатистикуКлассификаторов - Булево - флаг того, что данные по классификаторам будут включены в
//                                                    статистику.
//                                                    Под классификаторами понимаются справочники, ПВХ, планы
//                                                    счетов, ПВР, у которых в ПКО установлены
//                                                    СинхронизироватьПоИдентификатору. и
//                                                    ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли.
// 
Процедура ВыполнитьАнализСообщенияОбмена(ПараметрыАнализа = Неопределено) Экспорт
	
	ЧтениеСообщения = Неопределено; // см. ОписаниеЧтенияСообщения
	
	Если ЗначениеЗаполнено(УзелОбменаЗагрузкаДанных) Тогда
		УзелОбменаЗагрузкаДанныхОбъект = УзелОбменаЗагрузкаДанных.ПолучитьОбъект();
	КонецЕсли;
	
	Попытка
		
		УстановитьФлагОшибки(Ложь);
		
		ИспользоватьТранзакции = Ложь;
		
		ПолеСтрокаСообщенияОбОшибке = "";
		ПолеСостояниеОбменаДанными = Неопределено;
		ПолеРезультатВыполненияОбмена = Неопределено;
		ПолеВерсияФорматаВходящегоСообщенияОбмена = Неопределено;
		ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Ложь;
		ЕстьИнформацияОРегистрацииОбъекта = Ложь;
		ГлобальныйСтекНеЗаписанныхОбъектов = Новый Соответствие;
		СоответствиеПравилКонвертации = Новый Соответствие;
		
		ИнициализироватьВедениеПротоколаОбмена();
		
		ИнициализироватьМенеджерыИСообщения();
		
		// дата начала анализа
		СостояниеОбменаДанными().ДатаНачала = ТекущаяДатаСеанса();
		
		// Обнуляем значение модальной переменной.
		ПолеТаблицаДанныхЗаголовкаПакета = Неопределено;
		
		НачатьЧтениеСообщения(ЧтениеСообщения, Истина);
		Попытка
			
			// Зачитываем данные из сообщения обмена.
			ПроизвестиЧтениеДанныхВРежимеАнализа(ЧтениеСообщения, ПараметрыАнализа);
			
			Если ФлагОшибки() Тогда
				ВызватьИсключение НСтр("ru = 'Возникли ошибки при анализе данных.'");
			КонецЕсли;
			
			// Формируем временную таблицу данных.
			ТаблицаДанныхЗаголовкаПакетаВременная = ТаблицаДанныхЗаголовкаПакета().Скопировать(, "ТипИсточникаСтрокой, ТипПриемникаСтрокой, ПоляПоиска, ПоляТаблицы");
			ТаблицаДанныхЗаголовкаПакетаВременная.Свернуть("ТипИсточникаСтрокой, ТипПриемникаСтрокой, ПоляПоиска, ПоляТаблицы");
			
			// Сворачиваем таблицу данных заголовка пакета.
			ТаблицаДанныхЗаголовкаПакета().Свернуть(
				"ТипОбъектаСтрокой, ТипИсточникаСтрокой, ТипПриемникаСтрокой, СинхронизироватьПоИдентификатору, ЭтоКлассификатор, ЭтоУдалениеОбъекта, ИспользоватьПредварительныйПросмотр",
				"КоличествоОбъектовВИсточнике");
			//
			ТаблицаДанныхЗаголовкаПакета().Колонки.Добавить("ПоляПоиска",  одОписаниеТипа("Строка"));
			ТаблицаДанныхЗаголовкаПакета().Колонки.Добавить("ПоляТаблицы", одОписаниеТипа("Строка"));
			
			Для Каждого СтрокаТаблицы Из ТаблицаДанныхЗаголовкаПакета() Цикл
				
				Отбор = Новый Структура;
				Отбор.Вставить("ТипИсточникаСтрокой", СтрокаТаблицы.ТипИсточникаСтрокой);
				Отбор.Вставить("ТипПриемникаСтрокой", СтрокаТаблицы.ТипПриемникаСтрокой);
				
				СтрокиВременнойТаблицы = ТаблицаДанныхЗаголовкаПакетаВременная.НайтиСтроки(Отбор);
				
				СтрокаТаблицы.ПоляПоиска  = СтрокиВременнойТаблицы[0].ПоляПоиска;
				СтрокаТаблицы.ПоляТаблицы = СтрокиВременнойТаблицы[0].ПоляТаблицы;
				
			КонецЦикла;
			
			ВыполнитьОбработчикПослеЗагрузкиДанных();
			
			ЗакончитьЧтениеСообщения(ЧтениеСообщения);
			
		Исключение
			ПрерватьЧтениеСообщения(ЧтениеСообщения);
			ВызватьИсключение;
		КонецПопытки;
		
	Исключение
		Если ЧтениеСообщения <> Неопределено
			И ЧтениеСообщения.СообщениеБылоПринятоРанее Тогда
			ЗаписатьВПротоколВыполнения(174,,,,,,
				Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято);
		Иначе
			ЗаписатьВПротоколВыполнения(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецЕсли;
		
	КонецПопытки;
	
	ЗавершитьВедениеПротоколаОбмена();
	
	// дата окончания анализа
	СостояниеОбменаДанными().ДатаОкончания = ТекущаяДатаСеанса();
	
	// Фиксируем завершение анализа данных в РС.
	ЗафиксироватьЗавершениеЗагрузкиДанных();
	
	// Сбрасываем модальные переменные перед помещением обработки в платформенный кэш.
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСоответствиеТиповДанныхДляЗагрузки = Неопределено;
	ГлобальныйСтекНеЗаписанныхОбъектов = Неопределено;
	СоответствиеПравилКонвертации = Неопределено;
	ФайлОбмена = Неопределено;
	
КонецПроцедуры

#КонецОбласти

#Область ПроцедурыОбработкиСобытийВнешнегоСоединения

// Загружает данные из строки XML.
//
Процедура ВнешнееСоединениеВыполнитьЗагрузкуДанныхИзСтрокиXML(СтрокаXML) Экспорт
	
	Если УзелОбменаЗагрузкаДанныхОбъект = Неопределено
		И ЗначениеЗаполнено(УзелОбменаЗагрузкаДанных) Тогда
		УзелОбменаЗагрузкаДанныхОбъект = УзелОбменаЗагрузкаДанных.ПолучитьОбъект();
	КонецЕсли;
	
	ФайлОбмена.УстановитьСтроку(СтрокаXML);
	
	ЗаписатьПакетВФайлДляСборкиАрхива(СтрокаXML);
	
	ЧтениеСообщения = Неопределено;
	Попытка
		
		ПроизвестиЧтениеДанныхВРежимеВнешнегоСоединения(ЧтениеСообщения);
		
	Исключение
		
		Если ЧтениеСообщения <> Неопределено
			И ЧтениеСообщения.СообщениеБылоПринятоРанее Тогда
			ЗаписатьВПротоколВыполнения(174,,,,,,
				Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято);
		Иначе
			ЗаписатьВПротоколВыполнения(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецЕсли;
		
	КонецПопытки;
	
КонецПроцедуры

// Выполняет обработчик конвертации Перед загрузкой данных для внешнего соединения.
//
Процедура ВнешнееСоединениеОбработчикКонвертацииПередЗагрузкойДанных(Отказ) Экспорт
	
	// {Обработчик: ПередЗагрузкойДанных} Начало
	Если Не ПустаяСтрока(Конвертация.ПередЗагрузкойДанных) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПередЗагрузкойДанных(ФайлОбмена, Отказ);
				
			Иначе
				
				Выполнить(Конвертация.ПередЗагрузкойДанных);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(22, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				НСтр("ru = 'ПередЗагрузкойДанных (конвертация)'"));
			Отказ = Истина;
		КонецПопытки;
		
	КонецЕсли;
	
	Если Отказ Тогда // Отказ от загрузки данных
		Возврат;
	КонецЕсли;
	// {Обработчик: ПередЗагрузкойДанных} Окончание
	
КонецПроцедуры

// Процедура инициализации перед загрузкой данных через внешнее соединение.
//
Процедура ВнешнееСоединениеПередЗагрузкойДанных() Экспорт
	
	РежимЗагрузкиДанных = "ЗагрузкаВИнформационнуюБазу";
	
	ПолеСтрокаСообщенияОбОшибке = "";
	ПолеСостояниеОбменаДанными = Неопределено;
	ПолеРезультатВыполненияОбмена = Неопределено;
	ПолеСоответствиеТиповДанныхДляЗагрузки = Неопределено;
	ПолеСчетчикЗагруженныхОбъектов = Неопределено;
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСвойстваУзлаПланаОбмена = Неопределено;
	ПолеВерсияФорматаВходящегоСообщенияОбмена = Неопределено;
	
	ПараметрыАрхива = РегистрыСведений.НастройкиАрхиваСообщенийОбменов.ПолучитьНастройки(УзелОбменаЗагрузкаДанных);
	
	Если ПараметрыАрхива <> Неопределено И ПараметрыАрхива.КоличествоФайлов > 0 Тогда
		
		ПоместитьСообщениеВАрхивПриВнешнемСоединении = Истина;
		
		НомерПакета = 0;
		ВременныйКаталог = ПолучитьИмяВременногоФайла(); //АПК: 441 временный каталог будет удалена в процедуре СобратьИПоместитьСообщениеОбменаВАрхив 
		СоздатьКаталог(ВременныйКаталог);
		ВременныйКаталогДляСборкиАрхива = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(ВременныйКаталог);
		
		ЗаписатьЗаголовокСообщенияДляАрхива();
		
	Иначе
		
		ПоместитьСообщениеВАрхивПриВнешнемСоединении = Ложь;
		
	КонецЕсли;
	
	ГлобальныйСтекНеЗаписанныхОбъектов = Новый Соответствие;
	НомерПоследнегоПоискаПоСсылке = 0;
	
	ИнициализироватьМенеджерыИСообщения();
	
	УстановитьФлагОшибки(Ложь);
	
	ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных();
	
	ИнициализироватьВедениеПротоколаОбмена();
	
	ИнформацияОПользовательскихПоляхПоискаПриЗагрузкеДанных = Новый Соответствие;
	
	СоответствиеДопПараметровПоиска = Новый Соответствие;
	СоответствиеПравилКонвертации = Новый Соответствие;
	
	КоличествоВыполненныхОтложенныхДвиженийДокументов = 0;
	
	Если КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 0 Тогда
		КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 100;
	КонецЕсли;
	
	// Выполняем очистку правил обмена.
	Правила.Очистить();
	ТаблицаПравилКонвертации.Очистить();
	
	ФайлОбмена = Новый ЧтениеXML;
	
	ЕстьИнформацияОРегистрацииОбъекта = Ложь;
	ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Ложь;
	
КонецПроцедуры

// Выполняет обработчик После загрузки данных.
// Сбрасывает переменные и проводит отложенное проведение документов и запись объектов.
//
Процедура ВнешнееСоединениеПослеЗагрузкиДанных() Экспорт
	
	СобратьИПоместитьСообщениеОбменаВАрхив();
	
	// Отложенная запись того, что не записали.
	ПровестиЗаписьНеЗаписанныхОбъектов();
	
	// Обработчик ПослеЗагрузкиДанных
	Если Не ФлагОшибки() Тогда
		
		Если Не ПустаяСтрока(Конвертация.ПослеЗагрузкиДанных) Тогда
			
			Попытка
				
				Если ОтладкаОбработчиковЗагрузки Тогда
					
					ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиДанных();
					
				Иначе
					
					Выполнить(Конвертация.ПослеЗагрузкиДанных);
					
				КонецЕсли;
				
			Исключение
				ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(23, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
					НСтр("ru = 'ПослеЗагрузкиДанных (конвертация)'"));
			КонецПопытки;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Если Не ФлагОшибки() Тогда
		
		// Выполняем проведение документов в очереди.
		ВыполнитьОтложенноеПроведениеДокументов();
		ВыполнитьОтложеннуюЗаписьОбъектов();
		
	КонецЕсли;
	
	Если Не ФлагОшибки() Тогда
		
		НачатьТранзакцию();
		Попытка
			Блокировка = Новый БлокировкаДанных;
		    ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ИмяТаблицыПоСсылке(УзелОбменаЗагрузкаДанных));
		    ЭлементБлокировки.УстановитьЗначение("Ссылка", УзелОбменаЗагрузкаДанных);
		    Блокировка.Заблокировать();
			
			// Запишем информацию о номере входящего сообщения.
			ЗаблокироватьДанныеДляРедактирования(УзелОбменаЗагрузкаДанных);
			ОбъектУзла = УзелОбменаЗагрузкаДанных.ПолучитьОбъект();
			
			ОбъектУзла.НомерПринятого = НомерСообщения();
			ОбъектУзла.ОбменДанными.Загрузка = Истина;
			
			ОбъектУзла.Записать();
	
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			ЗаписатьИнформациюОбОшибкеВПротокол(173, ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()), ОбъектУзла);
		КонецПопытки;
		
	КонецЕсли;
	
	Если Не ФлагОшибки() Тогда
		
		Если ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Истина Тогда
			
			РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ЗафиксироватьВыполнениеКорректировкиИнформацииСопоставленияБезусловно(УзелОбменаЗагрузкаДанных);
			
		КонецЕсли;
		
		Если ЕстьИнформацияОРегистрацииОбъекта = Истина Тогда
			
			РегистрыСведений.СоответствияОбъектовИнформационныхБаз.УдалитьНеактуальныеЗаписиРежимаВыгрузкиПоСсылке(УзелОбменаЗагрузкаДанных);
			
		КонецЕсли;
		
	КонецЕсли;
	
	ЗавершитьВедениеПротоколаОбмена();
	
	// Сбрасываем модальные переменные перед помещением обработки в платформенный кэш.
	ПолеДокументыДляОтложенногоПроведения = Неопределено;
	ПолеОбъектыДляОтложеннойЗаписи = Неопределено;
	СоответствиеДокументовДляОтложенногоПроведения = Неопределено;
	ПолеСоответствиеТиповДанныхДляЗагрузки = Неопределено;
	ГлобальныйСтекНеЗаписанныхОбъектов = Неопределено;
	ФайлОбмена = Неопределено;
	
КонецПроцедуры

// Открывает новую транзакцию.
//
Процедура ВнешнееСоединениеПроверитьНачалоИФиксациюТранзакцииПриЗагрузкеДанных() Экспорт
	
	Если ИспользоватьТранзакции
		И КоличествоОбъектовНаТранзакцию > 0
		И СчетчикЗагруженныхОбъектов() % КоличествоОбъектовНаТранзакцию = 0 Тогда
		
		ЗафиксироватьТранзакцию();
		НачатьТранзакцию();
		
	КонецЕсли;
	
КонецПроцедуры

// Открывает транзакцию для обмена через внешнее соединение, если требуется.
//
Процедура ВнешнееСоединениеНачатьТранзакциюПриЗагрузкеДанных() Экспорт
	
	Если ИспользоватьТранзакции Тогда
		НачатьТранзакцию();
	КонецЕсли;
	
КонецПроцедуры

// Завершает транзакцию при обмене через внешнее соединение (если загрузка выполнялась в транзакции).
//
Процедура ВнешнееСоединениеЗафиксироватьТранзакциюПриЗагрузкеДанных() Экспорт
	
	Если ИспользоватьТранзакции Тогда
		
		Если ФлагОшибки() Тогда
			ОтменитьТранзакцию();
		Иначе
			ЗафиксироватьТранзакцию();
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

// Отменяет транзакцию при обмене через внешнее соединение.
//
Процедура ВнешнееСоединениеОтменитьТранзакциюПриЗагрузкеДанных() Экспорт
	
	Пока ТранзакцияАктивна() Цикл
		ОтменитьТранзакцию();
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область Прочее

// Выполняет помещение файла обмена в сервис хранения файлов для последующего сопоставления.
// Загрузка данных не выполняется.
//
Процедура ПоместитьСообщениеДляСопоставленияДанных(ДанныеВыгрузкиXML) Экспорт
	
	КаталогВыгрузки = ОбменДаннымиСервер.КаталогВременногоХранилищаФайлов();
	ИмяВременногоФайла = ОбменДаннымиСервер.УникальноеИмяФайлаСообщенияОбмена();
	
	ПолноеИмяВременногоФайла = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(
		КаталогВыгрузки, ИмяВременногоФайла);
		
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.ДобавитьСтроку(ДанныеВыгрузкиXML);
	ТекстовыйДокумент.Записать(ПолноеИмяВременногоФайла, , Символы.ПС);
	
	ИдентификаторФайла = ОбменДаннымиСервер.ПоместитьФайлВХранилище(ПолноеИмяВременногоФайла);
	
	ОбменДаннымиСлужебный.ПоместитьСообщениеДляСопоставленияДанных(УзелОбменаЗагрузкаДанных, ИдентификаторФайла);
	
КонецПроцедуры

// Устанавливает значение параметра "Загрузка" для свойства объекта "ОбменДанными".
//
// Параметры:
//   Объект - Произвольный - объект данных, для которого устанавливается свойство.
//   Значение - Булево - значение устанавливаемого свойства "Загрузка".
//   ОтправкаНазад - Булево
//
Процедура УстановитьОбменДаннымиЗагрузка(Объект, Значение = Истина, Знач ОтправкаНазад = Ложь) Экспорт
	
	ОбменДаннымиСервер.УстановитьОбменДаннымиЗагрузка(Объект, Значение, ОтправкаНазад, УзелОбменаЗагрузкаДанных);
	
КонецПроцедуры

// Подготавливает строку с информацией о правилах на основании зачитанных данных из XML-файла.
//
// Параметры:
//   ЭтоПравилаКорреспондента - Булево
// 
// Возвращаемое значение:
//   Строка - строка с информацией о правилах.
//
Функция ИнформацияОПравилах(ЭтоПравилаКорреспондента = Ложь) Экспорт
	
	// Возвращаемое значение функции.
	СтрокаИнформации = "";
	
	Если ФлагОшибки() Тогда
		Возврат СтрокаИнформации;
	КонецЕсли;
	
	Если ЭтоПравилаКорреспондента Тогда
		СтрокаИнформации = НСтр("ru = 'Правила конвертации корреспондента (%1) от %2'");
	Иначе
		СтрокаИнформации = НСтр("ru = 'Правила конвертации этой информационной базы (%1) от %2'");
	КонецЕсли;
	
	ПредставлениеКонфигурацииИсточника = ПредставлениеКонфигурацииИзПравилОбмена("Источника");
	
	Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаИнформации,
							ПредставлениеКонфигурацииИсточника,
							Формат(Конвертация.ДатаВремяСоздания, "ДЛФ =ДД"));
КонецФункции

// Устанавливает имя события для записи сообщений в журнал регистрации.
// 
// Параметры:
//   ИмяСобытия - Строка
//
Процедура УстановитьКлючСообщенияЖурналаРегистрации(ИмяСобытия) Экспорт
	
	КлючСообщенияЖурналаРегистрации = ИмяСобытия;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

#Область ВнутренниеСвойства

Функция ОбработкаДляЗагрузкиДанных()
	
	Возврат ПолеОбработкаДляЗагрузкиДанных;
	
КонецФункции

Функция ЭтоОбменЧерезВнешнееСоединение()
	
	Возврат ОбработкаДляЗагрузкиДанных() <> Неопределено
		И Не (ОбработкаДляЗагрузкиДанных().РежимЗагрузкиДанных = "ЗагрузкаСообщенияДляСопоставленияДанных");
	
КонецФункции
	
Функция ЭтоЗагрузкаСообщенияДляСопоставления()	
	
	Возврат ОбработкаДляЗагрузкиДанных() <> Неопределено
		И ОбработкаДляЗагрузкиДанных().РежимЗагрузкиДанных = "ЗагрузкаСообщенияДляСопоставленияДанных";
		
КонецФункции

Функция СостояниеОбменаДанными()
	
	Если ТипЗнч(ПолеСостояниеОбменаДанными) <> Тип("Структура") Тогда
		
		ПолеСостояниеОбменаДанными = Новый Структура;
		ПолеСостояниеОбменаДанными.Вставить("УзелИнформационнойБазы");
		ПолеСостояниеОбменаДанными.Вставить("ДействиеПриОбмене");
		ПолеСостояниеОбменаДанными.Вставить("РезультатВыполненияОбмена");
		ПолеСостояниеОбменаДанными.Вставить("ДатаНачала");
		ПолеСостояниеОбменаДанными.Вставить("ДатаОкончания");
		
	КонецЕсли;
	
	Возврат ПолеСостояниеОбменаДанными;
	
КонецФункции

Функция СоответствиеТиповДанныхДляЗагрузки()
	
	Если ТипЗнч(ПолеСоответствиеТиповДанныхДляЗагрузки) <> Тип("Соответствие") Тогда
		
		ПолеСоответствиеТиповДанныхДляЗагрузки = Новый Соответствие;
		
	КонецЕсли;
	
	Возврат ПолеСоответствиеТиповДанныхДляЗагрузки;
	
КонецФункции

Функция РежимЗагрузкиДанныхВТаблицуЗначений()
	
	Возврат Не РежимЗагрузкиДанныхВИнформационнуюБазу();
	
КонецФункции

Функция ИмяКолонкиУникальныйИдентификатор()
	
	Возврат "УникальныйИдентификатор";
	
КонецФункции

Функция ИмяКолонкиТипСтрокой()
	
	Возврат "ТипСтрокой";
	
КонецФункции

Функция КлючСообщенияЖурналаРегистрации()
	
	Если ТипЗнч(КлючСообщенияЖурналаРегистрации) <> Тип("Строка")
		ИЛИ ПустаяСтрока(КлючСообщенияЖурналаРегистрации) Тогда
		
		КлючСообщенияЖурналаРегистрации = ОбменДаннымиСервер.СобытиеЖурналаРегистрацииОбменДанными();
		
	КонецЕсли;
	
	Возврат КлючСообщенияЖурналаРегистрации;
КонецФункции

Функция ПриоритетыРезультатовОбмена()
	
	Если ТипЗнч(ПолеПриоритетыРезультатовОбмена) <> Тип("Массив") Тогда
		
		ПолеПриоритетыРезультатовОбмена = Новый Массив;
		ПолеПриоритетыРезультатовОбмена.Добавить(Перечисления.РезультатыВыполненияОбмена.Ошибка);
		ПолеПриоритетыРезультатовОбмена.Добавить(Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения);
		ПолеПриоритетыРезультатовОбмена.Добавить(Перечисления.РезультатыВыполненияОбмена.Отменено);
		ПолеПриоритетыРезультатовОбмена.Добавить(Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято);
		ПолеПриоритетыРезультатовОбмена.Добавить(Перечисления.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями);
		ПолеПриоритетыРезультатовОбмена.Добавить(Перечисления.РезультатыВыполненияОбмена.Выполнено);
		ПолеПриоритетыРезультатовОбмена.Добавить(Неопределено);
		
	КонецЕсли;
	
	Возврат ПолеПриоритетыРезультатовОбмена;
КонецФункции

Функция ТаблицыОписанийСвойствОбъектов()
	
	Если ТипЗнч(ПолеТаблицыОписанийСвойствОбъектов) <> Тип("Соответствие") Тогда
		
		ПолеТаблицыОписанийСвойствОбъектов = Новый Соответствие;
		
	КонецЕсли;
	
	Возврат ПолеТаблицыОписанийСвойствОбъектов;
КонецФункции

Функция ДополнительныеСвойстваДляОтложенногоПроведения()
	
	Если ТипЗнч(СоответствиеДокументовДляОтложенногоПроведения) <> Тип("Соответствие") Тогда
		
		// Инициализируем соответствие для отложенного проведения документов.
		СоответствиеДокументовДляОтложенногоПроведения = Новый Соответствие;
		
	КонецЕсли;
	
	Возврат СоответствиеДокументовДляОтложенногоПроведения;
	
КонецФункции

Функция ОбъектыДляОтложеннойЗаписи()
	
	Если ТипЗнч(ПолеОбъектыДляОтложеннойЗаписи) <> Тип("Соответствие") Тогда
		
		// Инициализируем соответствие для отложенной записи объектов.
		ПолеОбъектыДляОтложеннойЗаписи = Новый Соответствие;
		
	КонецЕсли;
	
	Возврат ПолеОбъектыДляОтложеннойЗаписи;
	
КонецФункции

Функция ВыгруженныеПоСсылкеОбъекты()
	
	Если ТипЗнч(ПолеВыгруженныеПоСсылкеОбъекты) <> Тип("Массив") Тогда
		
		ПолеВыгруженныеПоСсылкеОбъекты = Новый Массив;
		
	КонецЕсли;
	
	Возврат ПолеВыгруженныеПоСсылкеОбъекты;
КонецФункции

Функция СозданныеПриВыгрузкеОбъекты()
	
	Если ТипЗнч(ПолеСозданныеПриВыгрузкеОбъекты) <> Тип("Массив") Тогда
		
		ПолеСозданныеПриВыгрузкеОбъекты = Новый Массив;
		
	КонецЕсли;
	
	Возврат ПолеСозданныеПриВыгрузкеОбъекты;
КонецФункции

Функция ВыгружаемыеПоСсылкеОбъектыМетаданных()
	
	Если ТипЗнч(ПолеВыгружаемыеПоСсылкеОбъектыМетаданных) <> Тип("Соответствие") Тогда
		
		ПолеВыгружаемыеПоСсылкеОбъектыМетаданных = Новый Соответствие;
		
	КонецЕсли;
	
	Возврат ПолеВыгружаемыеПоСсылкеОбъектыМетаданных;
КонецФункции

Функция ВыгружатьОбъектПоСсылке(Объект, УзелПланаОбмена)
	
	ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
	
	Если ОбъектМетаданных = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	// получаем значение из кэша
	Результат = ВыгружаемыеПоСсылкеОбъектыМетаданных().Получить(ОбъектМетаданных);
	
	Если Результат = Неопределено Тогда
		
		Результат = Ложь;
		
		// Получаем признак выгрузки по ссылке.
		Отбор = Новый Структура("ОбъектМетаданныхИмя", ОбъектМетаданных.ПолноеИмя());
		
		МассивПравил = ПравилаРегистрацииОбъектов(УзелПланаОбмена).НайтиСтроки(Отбор);
		
		Для Каждого Правило Из МассивПравил Цикл
			
			Если Не ПустаяСтрока(Правило.ИмяРеквизитаФлага) Тогда
				
				ЗначениеРеквизитаФлага = Неопределено;
				СвойстваУзлаПланаОбмена(УзелПланаОбмена).Свойство(Правило.ИмяРеквизитаФлага, ЗначениеРеквизитаФлага);
				
				Результат = Результат ИЛИ ( ЗначениеРеквизитаФлага = Перечисления.РежимыВыгрузкиОбъектовОбмена.ВыгружатьПриНеобходимости
										ИЛИ ЗначениеРеквизитаФлага = Перечисления.РежимыВыгрузкиОбъектовОбмена.ПустаяСсылка());
				//
				Если Результат Тогда
					Прервать;
				КонецЕсли;
				
			КонецЕсли;
			
		КонецЦикла;
		
		// Сохраняем полученное значение в кэше.
		ВыгружаемыеПоСсылкеОбъектыМетаданных().Вставить(ОбъектМетаданных, Результат);
		
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

Функция ИмяПланаОбмена()
	
	Если ТипЗнч(ПолеИмяПланаОбмена) <> Тип("Строка")
		ИЛИ ПустаяСтрока(ПолеИмяПланаОбмена) Тогда
		
		Если ЗначениеЗаполнено(УзелДляОбмена) Тогда
			
			ПолеИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелДляОбмена);
			
		ИначеЕсли ЗначениеЗаполнено(УзелОбменаЗагрузкаДанных) Тогда
			
			ПолеИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелОбменаЗагрузкаДанных);
			
		ИначеЕсли ЗначениеЗаполнено(ИмяПланаОбменаВРО) Тогда
			
			ПолеИмяПланаОбмена = ИмяПланаОбменаВРО;
			
		Иначе
			
			ПолеИмяПланаОбмена = "";
			
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат ПолеИмяПланаОбмена;
КонецФункции

Функция СвойстваУзлаПланаОбмена(Узел)
	
	Если ТипЗнч(ПолеСвойстваУзлаПланаОбмена) <> Тип("Структура") Тогда
		
		ПолеСвойстваУзлаПланаОбмена = Новый Структура;
		
		// получаем имена реквизитов
		ИменаРеквизитов = ОбщегоНазначения.ИменаРеквизитовПоТипу(Узел, Тип("ПеречислениеСсылка.РежимыВыгрузкиОбъектовОбмена"));
		
		// Получаем значения реквизитов.
		Если Не ПустаяСтрока(ИменаРеквизитов) Тогда
			
			ПолеСвойстваУзлаПланаОбмена = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Узел, ИменаРеквизитов);
			
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат ПолеСвойстваУзлаПланаОбмена;
КонецФункции

Функция ВерсияФорматаВходящегоСообщенияОбмена()
	
	Если ТипЗнч(ПолеВерсияФорматаВходящегоСообщенияОбмена) <> Тип("Строка") Тогда
		
		ПолеВерсияФорматаВходящегоСообщенияОбмена = "0.0.0.0";
		
	КонецЕсли;
	
	// Дополняем версию формата входящего сообщения до 4-х разрядов.
	РазрядыВерсий = СтрРазделить(ПолеВерсияФорматаВходящегоСообщенияОбмена, ".");
	
	Если РазрядыВерсий.Количество() < 4 Тогда
		
		КоличествоРазрядовДобавить = 4 - РазрядыВерсий.Количество();
		
		Для А = 1 По КоличествоРазрядовДобавить Цикл
			
			РазрядыВерсий.Добавить("0");
			
		КонецЦикла;
		
		ПолеВерсияФорматаВходящегоСообщенияОбмена = СтрСоединить(РазрядыВерсий, ".");
		
	КонецЕсли;
	
	Возврат ПолеВерсияФорматаВходящегоСообщенияОбмена;
КонецФункции

Функция НомерСообщения()
	
	Если ТипЗнч(ПолеНомерСообщения) <> Тип("Число") Тогда
		
		ПолеНомерСообщения = 0;
		
	КонецЕсли;
	
	Возврат ПолеНомерСообщения;
	
КонецФункции

#КонецОбласти

#Область ФункцииКэширования

Функция ТаблицаОписанияСвойствОбъекта(ОбъектМетаданных)
	
	Результат = ТаблицыОписанийСвойствОбъектов().Получить(ОбъектМетаданных);
	
	Если Результат = Неопределено Тогда
		
		Результат = ОбщегоНазначения.ОписаниеСвойствОбъекта(ОбъектМетаданных, "Имя");
		
		ТаблицыОписанийСвойствОбъектов().Вставить(Результат);
		
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

Функция ПравилаРегистрацииОбъектов(УзелПланаОбмена)
	
	Если ТипЗнч(ПолеПравилаРегистрацииОбъектов) <> Тип("ТаблицаЗначений") Тогда
		
		ПравилаРегистрацииОбъектов = ОбменДаннымиСобытия.ПравилаРегистрацииОбъектовПланаОбмена(
			ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелПланаОбмена));
		ПолеПравилаРегистрацииОбъектов = ПравилаРегистрацииОбъектов.Скопировать(, "ОбъектМетаданныхИмя, ИмяРеквизитаФлага"); // ТаблицаЗначений
		ПолеПравилаРегистрацииОбъектов.Индексы.Добавить("ОбъектМетаданныхИмя");
		
	КонецЕсли;
	
	Возврат ПолеПравилаРегистрацииОбъектов;
	
КонецФункции

#КонецОбласти

#Область ВспомогательныеПроцедурыДляНаписанияАлгоритмов

#Область РаботаСоСтроками

// Разбирает строку на две части: до подстроки разделителя и после.
//
// Параметры:
//  Стр          - разбираемая строка;
//  Разделитель  - подстрока-разделитель:
//  Режим        - 0 - разделитель в возвращаемые подстроки не включается;
//                 1 - разделитель включается в левую подстроку;
//                 2 - разделитель включается в правую подстроку.
//
// Возвращаемое значение:
//  Правая часть строки - до символа-разделителя.
// 
Функция ОтделитьРазделителем(Стр, Знач Разделитель, Режим=0)

	ПраваяЧасть         = "";
	ПозРазделителя      = СтрНайти(Стр, Разделитель);
	ДлинаРазделителя    = СтрДлина(Разделитель);
	Если ПозРазделителя > 0 Тогда
		ПраваяЧасть	 = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя));
		Стр          = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя + 1, 1)));
	КонецЕсли;

	Возврат(ПраваяЧасть);

КонецФункции

// Преобразует значения из строки в массив, используя указанный разделитель.
//
// Параметры:
//  Стр            - разбираемая строка.
//  Разделитель    - подстрока разделитель.
//
// Возвращаемое значение:
//  Массив значений
// 
Функция МассивИзСтроки(Знач Стр, Разделитель=",")

	Массив      = Новый Массив;
	ПраваяЧасть = ОтделитьРазделителем(Стр, Разделитель);
	
	Пока Не ПустаяСтрока(Стр) Цикл
		Массив.Добавить(СокрЛП(Стр));
		Стр         = ПраваяЧасть;
		ПраваяЧасть = ОтделитьРазделителем(Стр, Разделитель);
	КонецЦикла; 

	Возврат(Массив);
	
КонецФункции

Функция СтроковыйНомерБезПрефиксов(Номер)
	
	НомерБезПрефиксов = "";
	Сч = СтрДлина(Номер);
	
	Пока Сч > 0 Цикл
		
		Символ = Сред(Номер, Сч, 1);
		
		Если (Символ >= "0" И Символ <= "9") Тогда
			
			НомерБезПрефиксов = Символ + НомерБезПрефиксов;
			
		Иначе
			
			Возврат НомерБезПрефиксов;
			
		КонецЕсли;
		
		Сч = Сч - 1;
		
	КонецЦикла;
	
	Возврат НомерБезПрефиксов;
	
КонецФункции

// Разбирает строку, выделяя из нее префикс и числовую часть.
//
// Параметры:
//  Стр            - Строка - разбираемая строка;
//  ЧисловаяЧасть  - Число - переменная, в которую возвратится числовая часть строки;
//  Режим          - Строка - если "Число", то возвратит числовую часть, иначе - префикс.
//
// Возвращаемое значение:
//  Префикс строки
//
Функция ПрефиксЧислоНомера(Знач Стр, ЧисловаяЧасть = "", Режим = "")

	ЧисловаяЧасть = 0;
	Префикс = "";
	Стр = СокрЛП(Стр);
	Длина   = СтрДлина(Стр);
	
	СтроковыйНомерБезПрефикса = СтроковыйНомерБезПрефиксов(Стр);
	ДлинаСтроковойЧасти = СтрДлина(СтроковыйНомерБезПрефикса);
	Если ДлинаСтроковойЧасти > 0 Тогда
		ЧисловаяЧасть = Число(СтроковыйНомерБезПрефикса);
		Префикс = Сред(Стр, 1, Длина - ДлинаСтроковойЧасти);
	Иначе
		Префикс = Стр;	
	КонецЕсли;

	Если Режим = "Число" Тогда
		Возврат(ЧисловаяЧасть);
	Иначе
		Возврат(Префикс);
	КонецЕсли;

КонецФункции

// Приводит номер (код) к требуемой длине. При этом выделяется префикс
// и числовая часть номера, остальное пространство между префиксом и
// номером заполняется нулями.
// Функция может быть использована в обработчиках событий, программный код 
// которых хранится в правила обмена данными. Вызывается методом Выполнить().
// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации 
// не является ошибкой проверки конфигурации.
//
// Параметры:
//  Стр          - Строка- преобразовываемая строка;
//  Длина        - Число - требуемая длина строки.
//
// Возвращаемое значение:
//  Строка       - код или номер, приведенная к требуемой длине.
// 
Функция ПривестиНомерКДлине(Знач Стр, Длина, ДобавлятьНулиЕслиДлинаНеМеньшеТекущейДлиныНомера = Истина, Префикс = "")

	Стр             = СокрЛП(Стр);
	ВходящаяДлинаНомера = СтрДлина(Стр);

	ЧисловаяЧасть   = "";
	Результат       = ПрефиксЧислоНомера(Стр, ЧисловаяЧасть);
	
	Результат = ?(ПустаяСтрока(Префикс), Результат, Префикс);
	
	СтрокаЧисловойЧасти = Формат(ЧисловаяЧасть, "ЧГ=0");
	ДлинаЧисловойЧасти = СтрДлина(СтрокаЧисловойЧасти);

	Если (Длина >= ВходящаяДлинаНомера И ДобавлятьНулиЕслиДлинаНеМеньшеТекущейДлиныНомера)
		ИЛИ (Длина < ВходящаяДлинаНомера) Тогда
		
		Для ВременнаяПеременная = 1 По Длина - СтрДлина(Результат) - ДлинаЧисловойЧасти Цикл
			
			Результат = Результат + "0";
			
		КонецЦикла;
	
	КонецЕсли;
		
	Результат = Результат + СтрокаЧисловойЧасти;

	Возврат(Результат);

КонецФункции

// Дополняет строку указанным символом до указанной длины.
//
// Параметры:
//  Стр          - Строка - дополняемая строка;
//  Длина        - Число - требуемая длина результирующей строки;
//  Чем          - Строка - символ, которым дополняется строка.
//
// Возвращаемое значение:
//  Строка - дополненная указанным символом до указанной длины.
//
Функция одДополнитьСтроку(Стр, Длина, Чем = " ")

	Результат = СокрЛП(Стр);
	Пока Длина - СтрДлина(Результат) > 0 Цикл
		Результат = Результат + Чем;
	КонецЦикла;

	Возврат(Результат);

КонецФункции

#КонецОбласти

#Область РаботаСДанными

// Определяет заполнено ли переданное значение.
//
// Параметры:
//  Значение       - значение, заполнение которого надо проверить.
//
// Возвращаемое значение:
//   Булево - Истина         - значение не заполнено, ложь - иначе.
//
Функция одПустое(Значение, ЭтоNULL=Ложь)

	// Сначала примитивные типы
	Если Значение = Неопределено Тогда
		Возврат Истина;
	ИначеЕсли Значение = NULL Тогда
		ЭтоNULL   = Истина;
		Возврат Истина;
	КонецЕсли;
	
	ТипЗначения = ТипЗнч(Значение);
	
	Если ТипЗначения = ТипХранилищеЗначения Тогда
		
		Результат = одПустое(Значение.Получить());
		Возврат Результат;		
		
	ИначеЕсли ТипЗначения = ТипДвоичныеДанные Тогда
		
		Возврат Ложь;
		
	Иначе
		
		// Для остальных будем считать значение пустым, если оно равно
		// значению по умолчанию своего типа.
		Попытка
			Результат = Не ЗначениеЗаполнено(Значение);
			Возврат Результат;
		Исключение
			Возврат Ложь;
		КонецПопытки;
			
	КонецЕсли;
	
КонецФункции

// Возвращает объект ОписаниеТипов, содержащий указанный тип.
//
// Параметры:
//  ЗначениеТипа - строка с именем типа или значение Тип - типа Тип.
//
// Возвращаемое значение:
//  ОписаниеТипов
//
Функция одОписаниеТипа(ЗначениеТипа)

	ОписаниеТипов = СоответствиеОписаниеТипов[ЗначениеТипа];
	
	Если ОписаниеТипов = Неопределено Тогда
		
		МассивТипов = Новый Массив;
		Если ТипЗнч(ЗначениеТипа) = ТипСтрока Тогда
			МассивТипов.Добавить(Тип(ЗначениеТипа));
		Иначе
			МассивТипов.Добавить(ЗначениеТипа);
		КонецЕсли; 
		ОписаниеТипов	= Новый ОписаниеТипов(МассивТипов);
		
		СоответствиеОписаниеТипов.Вставить(ЗначениеТипа, ОписаниеТипов);
		
	КонецЕсли;	
	
	Возврат ОписаниеТипов;

КонецФункции

// Возвращает пустое (дефолтное) значение указанного типа.
//
// Параметры:
//  Тип          - строка с именем типа или значение Тип - типа Тип.
//
// Возвращаемое значение:
//  Пустое значение указанного типа.
//
Функция одПолучитьПустоеЗначение(Тип)

	ПустоеЗначениеТипа = СоответствиеПустыхЗначенийТипов[Тип];
	
	Если ПустоеЗначениеТипа = Неопределено Тогда
		
		ПустоеЗначениеТипа = одОписаниеТипа(Тип).ПривестиЗначение(Неопределено);	
		
		СоответствиеПустыхЗначенийТипов.Вставить(Тип, ПустоеЗначениеТипа);
			
	КонецЕсли;
	
	Возврат ПустоеЗначениеТипа;

КонецФункции

Функция ПроверитьСуществованиеСсылки(Ссылка, Менеджер, НайденныйОбъектПоУникальномуИдентификатору, 
	РежимПоискаОсновногоОбъекта, СтрокаЗапросаПоискаПоУникальномуИдентификатору)
	
	Попытка
			
		Если РежимПоискаОсновногоОбъекта
			ИЛИ ПустаяСтрока(СтрокаЗапросаПоискаПоУникальномуИдентификатору) Тогда
			
			НайденныйОбъектПоУникальномуИдентификатору = Ссылка.ПолучитьОбъект();
			
			Если НайденныйОбъектПоУникальномуИдентификатору = Неопределено Тогда
			
				Возврат Менеджер.ПустаяСсылка();
				
			КонецЕсли;
			
		Иначе
			// Это режим поиска по ссылке - достаточно сделать запрос к информационной базе
			// шаблон для запроса СтруктураСвойств.СтрокаПоиска.
			
			Запрос = Новый Запрос();
			Запрос.Текст = СтрокаЗапросаПоискаПоУникальномуИдентификатору + "  Ссылка = &Ссылка ";
			Запрос.УстановитьПараметр("Ссылка", Ссылка);
			
			РезультатЗапроса = Запрос.Выполнить();
			
			Если РезультатЗапроса.Пустой() Тогда
			
				Возврат Менеджер.ПустаяСсылка();
				
			КонецЕсли;
			
		КонецЕсли;
		
		Возврат Ссылка;	
		
	Исключение
			
		Возврат Менеджер.ПустаяСсылка();
		
	КонецПопытки;
	
КонецФункции

// Осуществляет простой поиск объекта информационной базы по указанному свойству.
//
// Параметры:
//  Менеджер       - менеджер искомого объекта;
//  Свойство       - свойство, по которому осуществляем поиск: Имя, Код, 
//                   Наименование или Имя индексируемого реквизита;
//  Значение       - значение свойства, по которому ищем объект.
//
// Возвращаемое значение:
//  Найденный объект информационной базы.
//
Функция одНайтиОбъектПоСвойству(Менеджер, Свойство, Значение, 
	НайденныйОбъектПоУникальномуИдентификатору = Неопределено, 
	ОбщаяСтруктураСвойств = Неопределено, ОбщиеСвойстваПоиска = Неопределено,
	РежимПоискаОсновногоОбъекта = Истина, СтрокаЗапросаПоискаПоУникальномуИдентификатору = "")
	
	Если Свойство = "Имя" Тогда
		
		Возврат Менеджер[Значение];
		
	ИначеЕсли Свойство = "{УникальныйИдентификатор}" Тогда
		
		СсылкаПоИдентификатору = Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(Значение));
		
		Ссылка =  ПроверитьСуществованиеСсылки(СсылкаПоИдентификатору, Менеджер, НайденныйОбъектПоУникальномуИдентификатору, 
			РежимПоискаОсновногоОбъекта, СтрокаЗапросаПоискаПоУникальномуИдентификатору);
			
		Возврат Ссылка;
		
	ИначеЕсли Свойство = "{ИмяПредопределенногоЭлемента}" Тогда
		
		Ссылка = ПредопределенныйЭлементМенеджера(Менеджер, Значение);
		Если Ссылка = Неопределено Тогда
			Ссылка = Менеджер.НайтиПоКоду(Значение);
			Если Ссылка = Неопределено Тогда
				Ссылка = Менеджер.ПустаяСсылка();
			КонецЕсли;
		КонецЕсли;
		
		Возврат Ссылка;
		
	Иначе
		
		СсылкаНаОбъект = НайтиЭлементЗапросом(ОбщаяСтруктураСвойств, ОбщиеСвойстваПоиска, , Менеджер);
		
		Возврат СсылкаНаОбъект;
		
	КонецЕсли;
	
КонецФункции

// Возвращает значение предопределенного элемента по его имени.
// 
Функция ПредопределенныйЭлементМенеджера(Знач Менеджер, Знач ИмяПредопределенного)
	
	ШаблонТекстаЗапроса = 
	"ВЫБРАТЬ
	|	ПсевдонимТаблицыМетаданных.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных,
	|	ПсевдонимТаблицыМетаданных.Ссылка КАК Ссылка
	|ИЗ
	|	&ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных
	|ГДЕ
	|	ПсевдонимТаблицыМетаданных.Предопределенный";
	
	СтрокаЗамены = Метаданные.НайтиПоТипу(ТипЗнч(Менеджер)).ПолноеИмя();
	ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ИмяТаблицыМетаданных", СтрокаЗамены);
	Запрос = Новый Запрос(ТекстЗапроса);
	
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.НайтиСледующий(Новый Структура("ИмяПредопределенныхДанных", ИмяПредопределенного)) Тогда
		
		Возврат Выборка.Ссылка;
		
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

// Осуществляет простой поиск объекта информационной базы по указанному свойству.
//
// Параметры:
//  Стр            - Строка - значение свойства, по которому осуществляется 
//                   поиск объект;
//  Тип            - тип искомого объекта;
//  Свойство       - Строка - имя свойства, по-которому ищем объект.
//
// Возвращаемое значение:
//  Найденный объект информационной базы.
//
Функция одПолучитьЗначениеПоСтроке(Стр, Тип, Свойство = "")

	Если ПустаяСтрока(Стр) Тогда
		Возврат Новый(Тип);
	КонецЕсли; 

	Свойства = Менеджеры[Тип];

	Если Свойства = Неопределено Тогда
		
		ОписаниеТипов = одОписаниеТипа(Тип);
		Возврат ОписаниеТипов.ПривестиЗначение(Стр);
		
	КонецЕсли;

	Если ПустаяСтрока(Свойство) Тогда
		
		Если Свойства.ИмяТипа = "Перечисление"
			Или Свойства.ИмяТипа = "ТочкаМаршрутаБизнесПроцесса" Тогда
			Свойство = "Имя";
		Иначе
			Свойство = "{ИмяПредопределенногоЭлемента}";
		КонецЕсли;
		
	КонецЕсли; 

	Возврат одНайтиОбъектПоСвойству(Свойства.Менеджер, Свойство, Стр);

КонецФункции

// Возвращает строковое представление типа значения.
//
// Параметры: 
//  ЗначениеИлиТип - произвольное значение или значение типа тип.
//
// Возвращаемое значение:
//  Строка - строковое представление типа значения.
//
Функция одТипЗначенияСтрокой(ЗначениеИлиТип)

	ТипЗначения	= ТипЗнч(ЗначениеИлиТип);
	
	Если ТипЗначения = ТипТип Тогда
		ТипЗначения	= ЗначениеИлиТип;
	КонецЕсли; 
	
	Если (ТипЗначения = Неопределено) Или (ЗначениеИлиТип = Неопределено) Тогда
		Результат = "";
	ИначеЕсли ТипЗначения = ТипСтрока Тогда
		Результат = "Строка";
	ИначеЕсли ТипЗначения = ТипЧисло Тогда
		Результат = "Число";
	ИначеЕсли ТипЗначения = ТипДата Тогда
		Результат = "Дата";
	ИначеЕсли ТипЗначения = ТипБулево Тогда
		Результат = "Булево";
	ИначеЕсли ТипЗначения = ТипХранилищеЗначения Тогда
		Результат = "ХранилищеЗначения";
	ИначеЕсли ТипЗначения = ТипУникальныйИдентификатор Тогда
		Результат = "УникальныйИдентификатор";
	ИначеЕсли ТипЗначения = ТипВидДвиженияНакопления Тогда
		Результат = "ВидДвиженияНакопления";
	ИначеЕсли ТипЗначения = ТипОписаниеТипов Тогда
		Результат = "ОписаниеТипов";
	Иначе
		Менеджер = Менеджеры[ТипЗначения];
		Если Менеджер = Неопределено Тогда
		Иначе
			Результат = Менеджер.ТипСсылкиСтрокой;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

#Область РаботаСОписаниемТипов

Функция ОписаниеТиповВJSON(ЗначениеОписаниеТипов)
	
	МассивТиповОписанияТипов = ЗначениеОписаниеТипов.Типы();
	ЭтоСоставнойТип = (МассивТиповОписанияТипов.Количество() > 1);
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписьJSON.ЗаписатьНачалоОбъекта();
	ЗаписьJSON.ЗаписатьИмяСвойства("TypeDescription");
	
	ЗаписьJSON.ЗаписатьНачалоМассива();
	
	ЗаписьJSON.ЗаписатьНачалоОбъекта();
	ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "multiple", Строка(ЭтоСоставнойТип));
	ЗаписьJSON.ЗаписатьКонецОбъекта();
	
	Для каждого ТипЗначенияОписанияТипов Из МассивТиповОписанияТипов Цикл
		
		ТипОписания = ТипЗнч(ТипЗначенияОписанияТипов);
		Если ТипОписания <> Тип("Тип") Тогда
			
			Продолжить;
			
		КонецЕсли;
		
		ЗаписьJSON.ЗаписатьНачалоОбъекта();
		
		ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗначенияОписанияТипов);
		Если ОбъектМетаданных = Неопределено Тогда
			
			СериализоватьОписаниеПримитивногоТипа(ЗаписьJSON, ТипЗначенияОписанияТипов, ЗначениеОписаниеТипов);
			
		Иначе
			
			СериализоватьОписаниеСсылочногоТипа(ЗаписьJSON, ОбъектМетаданных);
			
		КонецЕсли;
		
		ЗаписьJSON.ЗаписатьКонецОбъекта();
		
	КонецЦикла;
	
	ЗаписьJSON.ЗаписатьКонецМассива();
	ЗаписьJSON.ЗаписатьКонецОбъекта(); // "TypeDescription"
	
	Возврат ЗаписьJSON.Закрыть();
	
КонецФункции

Функция ОписаниеТиповИзJSON(ТекстJSON)
	
	ОписаниеТиповТипаЗначения = Новый ОписаниеТипов;
	Если ПустаяСтрока(ТекстJSON) Тогда
		
		Возврат ОписаниеТиповТипаЗначения;
		
	КонецЕсли;
	
	МассивИменОписанийТипов = Новый Массив;
	
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(ТекстJSON);
	
	КвалификаторСтрокиДлина = 0;
	КвалификаторСтрокиДопустимаяДлина = ДопустимаяДлина.Переменная;
	
	КвалификаторЧислаРазрядность = 0;
	КвалификаторЧислаРазрядностьДробнойЧасти = 0;
	КвалификаторЧислаДопустимыйЗнак = ДопустимыйЗнак.Любой;
	
	КвалификаторДатыЧастиДаты = ЧастиДаты.ДатаВремя;
	
	Пока ЧтениеJSON.Прочитать() Цикл
		
		Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.ИмяСвойства Тогда
			
			Если ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("TypeDescription") Тогда
				
				Продолжить;
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("multiple") Тогда
				
				ЧтениеJSON.Прочитать();
				// Признак составного типа, далее не используется
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("typeFeatures") Тогда
				
				ИмяТипаСтрокой = "";
				
				ЧтениеJSON.Прочитать();
				
				ИмяТипаСтрокой = СокрЛП(ЧтениеJSON.ТекущееЗначение);
				Если ВРег(ИмяТипаСтрокой) = ВРег("String") Тогда
					
					МассивИменОписанийТипов.Добавить(Тип("Строка"));
					
				ИначеЕсли ВРег(ИмяТипаСтрокой) = ВРег("number") Тогда
					
					МассивИменОписанийТипов.Добавить(Тип("Число"));
					
				ИначеЕсли ВРег(ИмяТипаСтрокой) = ВРег("Date") Тогда
					
					МассивИменОписанийТипов.Добавить(Тип("Дата"));
					
				ИначеЕсли ВРег(ИмяТипаСтрокой) = ВРег("Boolean") Тогда
					
					МассивИменОписанийТипов.Добавить(Тип("Булево"));
					
				Иначе 
					
					Попытка
						
						// Обязательно необходимо использовать попытку, т.к. при переименовании объектов,
						// например, ДоговорЛизинга (2.4) в ДоговорАренды (2.5) возникает ошибка получения типа.
						МассивИменОписанийТипов.Добавить(Тип(ИмяТипаСтрокой));
						
					Исключение
						
						// Необходимо пропустить исключение для типов, которые переименованы или удалены
						ТекстКомментария = НСтр("ru ='Метаданные не обнаружены: %1.'", ОбщегоНазначения.КодОсновногоЯзыка());
						ТекстКомментария = СтрШаблон(ТекстКомментария, ИмяТипаСтрокой);
						
						ЗаписьЖурналаРегистрацииОбменДанными(ТекстКомментария, УровеньЖурналаРегистрации.Предупреждение);						
						
					КонецПопытки;
					
				КонецЕсли;
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("lengthStr") Тогда
				
				ЧтениеJSON.Прочитать();
				КвалификаторСтрокиДлина = Число(ЧтениеJSON.ТекущееЗначение);
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("typeStr") Тогда
				
				ЧтениеJSON.Прочитать();
				Если НЕ ПустаяСтрока(ЧтениеJSON.ТекущееЗначение) Тогда
					
					КвалификаторСтрокиДопустимаяДлина = ДопустимаяДлина[ЧтениеJSON.ТекущееЗначение];
					
				КонецЕсли;
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("lengthInt") Тогда
				
				ЧтениеJSON.Прочитать();
				КвалификаторЧислаРазрядность = Число(ЧтениеJSON.ТекущееЗначение);
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("decimal") Тогда
				
				ЧтениеJSON.Прочитать();
				КвалификаторЧислаРазрядностьДробнойЧасти = Число(ЧтениеJSON.ТекущееЗначение);
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("sign") Тогда
				
				ЧтениеJSON.Прочитать();
				Если ВРег(ЧтениеJSON.ТекущееЗначение) <> ВРег("any") Тогда
					
					КвалификаторЧислаДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный;
					
				КонецЕсли;
				
			ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("typeDate") Тогда
				
				ЧтениеJSON.Прочитать();
				Если ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("Data") Тогда
					
					КвалификаторДатыЧастиДаты = ЧастиДаты.Дата;
					
				ИначеЕсли ВРег(ЧтениеJSON.ТекущееЗначение) = ВРег("Time") Тогда
					
					КвалификаторДатыЧастиДаты = ЧастиДаты.Время;
					
				КонецЕсли;
				
			КонецЕсли;
			
		ИначеЕсли ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта
			ИЛИ ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоМассива
			ИЛИ ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.КонецОбъекта
			ИЛИ ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.КонецМассива Тогда
			
			Продолжить;
			
		КонецЕсли;
		
	КонецЦикла;
	
	КвалификаторТипаСтрока = Новый КвалификаторыСтроки(КвалификаторСтрокиДлина, КвалификаторСтрокиДопустимаяДлина);
	КвалификаторТипаЧисло = Новый КвалификаторыЧисла(КвалификаторЧислаРазрядность,КвалификаторЧислаРазрядностьДробнойЧасти,КвалификаторЧислаДопустимыйЗнак);
	КвалификаторТипаДата = Новый КвалификаторыДаты(КвалификаторДатыЧастиДаты);
	
	Возврат Новый ОписаниеТипов(МассивИменОписанийТипов, , , КвалификаторТипаЧисло, КвалификаторТипаСтрока, КвалификаторТипаДата);
	
КонецФункции

Процедура ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, ИмяСвойства, ЗначениеСвойства)
	
	ЗаписьJSON.ЗаписатьИмяСвойства(ИмяСвойства);
	ЗаписьJSON.ЗаписатьЗначение(ЗначениеСвойства);
	
КонецПроцедуры

Процедура СериализоватьОписаниеПримитивногоТипа(ЗаписьJSON, ТипЗначенияОписанияТипов, ЗначениеОписаниеТипов)
	
	Если ТипЗначенияОписанияТипов = Тип("Строка") Тогда
		
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "typeFeatures", "string");
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "lengthStr", Строка(ЗначениеОписаниеТипов.КвалификаторыСтроки.Длина));
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "typeStr", Строка(ЗначениеОписаниеТипов.КвалификаторыСтроки.ДопустимаяДлина));
		
	ИначеЕсли ТипЗначенияОписанияТипов = Тип("Число") Тогда
		
		ДопустимыйЗнакЧисла = ЗначениеОписаниеТипов.КвалификаторыЧисла.ДопустимыйЗнак;
		
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "typeFeatures", "number");
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "lengthInt", ЗначениеОписаниеТипов.КвалификаторыЧисла.Разрядность);
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "decimal", ЗначениеОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти);
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "sign", ?(ДопустимыйЗнакЧисла = ДопустимыйЗнак.Любой, "any", "non-negative"));
		
	ИначеЕсли ТипЗначенияОписанияТипов = Тип("Дата") Тогда
		
		ОписаниеЧастейДаты = "dateTime";
		Если ЗначениеОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
			
			ОписаниеЧастейДаты = "data";
			
		ИначеЕсли ЗначениеОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда
			
			ОписаниеЧастейДаты = "time";
			
		КонецЕсли;
		
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "typeFeatures", "date");
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "typeDate", ОписаниеЧастейДаты);
		
	ИначеЕсли ТипЗначенияОписанияТипов = Тип("Булево") Тогда
		
		ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "typeFeatures", "boolean");
		
	КонецЕсли;
	
КонецПроцедуры

Процедура СериализоватьОписаниеСсылочногоТипа(ЗаписьJSON, ОбъектМетаданных)
	
	ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
	ПолноеИмя = СтрЗаменить(ПолноеИмя, ".", "Ссылка.");
	
	ДобавитьСвойствоИЗначениеJSON(ЗаписьJSON, "typeFeatures", ПолноеИмя);
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#КонецОбласти

#Область ПроцедурыИФункцииРаботыСОбъектомXMLЗапись

// Создает новый xml-узел.
// Функция может быть использована в обработчиках событий, программный код 
// которых хранится в правила обмена данными. Вызывается методом Выполнить().
//
// Параметры: 
//   Имя - Строка - имя узла.
//
// Возвращаемое значение:
//   ЗаписьXML - объект нового xml-узла.
//
Функция СоздатьУзел(Имя)

	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	ЗаписьXML.ЗаписатьНачалоЭлемента(Имя);

	Возврат ЗаписьXML;

КонецФункции

// Осуществляет запись элемента и его значения в указанный объект.
//
// Параметры:
//  Объект         - объект типа ЗаписьXML.
//  Имя            - Строка - имя элемента.
//  Значение       - значение элемента.
//
Процедура одЗаписатьЭлемент(Объект, Имя, Значение="")

	Объект.ЗаписатьНачалоЭлемента(Имя);
	Стр = XMLСтрока(Значение);
	
	Объект.ЗаписатьТекст(Стр);
	Объект.ЗаписатьКонецЭлемента();
	
КонецПроцедуры

// Подчиняет xml-узел указанному узлу-родителю.
//
// Параметры: 
//  УзелРодитель   - xml-узел-родитель.
//  Узел           - подчиняемый узел.
//
Процедура ДобавитьПодчиненный(УзелРодитель, Узел)

	Если ТипЗнч(Узел) <> ТипСтрока Тогда
		Узел.ЗаписатьКонецЭлемента();
		ИнформацияДляЗаписиВФайл = Узел.Закрыть();
	Иначе
		ИнформацияДляЗаписиВФайл = Узел;
	КонецЕсли;
	
	УзелРодитель.ЗаписатьБезОбработки(ИнформацияДляЗаписиВФайл);
		
КонецПроцедуры

// Устанавливает атрибут указанного xml-узла.
//
// Параметры: 
//  Узел           - xml-узел
//  Имя            - имя атрибута.
//  Значение       - устанавливаемое значение.
//
Процедура УстановитьАтрибут(Узел, Имя, Значение)

	СтрокаЗаписи = XMLСтрока(Значение);
	
	Узел.ЗаписатьАтрибут(Имя, СтрокаЗаписи);
	
КонецПроцедуры

#КонецОбласти

#Область ПроцедурыИФункцииРаботыСОбъектомXMLЧтение

// Читает значение атрибута по имени из указанного объекта, приводит значение
// к указанному примитивному типу.
//
// Параметры:
//  Объект      - объект типа ЧтениеXML, спозиционированный на начале элемента,
//                атрибут которого требуется получить.
//  Тип         - значение Тип - типа Тип. Тип атрибута.
//  Имя         - Строка - имя атрибута.
//
// Возвращаемое значение:
//  Значение атрибута полученное по имени и приведенное к указанному типу.
//
Функция одАтрибут(Объект, Тип, Имя)

	СтрЗначение = СокрП(Объект.ПолучитьАтрибут(Имя));
	Если Не ПустаяСтрока(СтрЗначение) Тогда
		Возврат XMLЗначение(Тип, СтрЗначение);		
	ИначеЕсли      Тип = ТипСтрока Тогда
		Возврат ""; 
	ИначеЕсли Тип = ТипБулево Тогда
		Возврат Ложь;
	ИначеЕсли Тип = ТипЧисло Тогда
		Возврат 0;
	ИначеЕсли Тип = ТипДата Тогда
		Возврат ЗначениеПустаяДата;
	КонецЕсли; 
	
КонецФункции

// Пропускает узлы xml до конца указанного элемента (по умолчанию текущего).
//
// Параметры:
//  Объект   - объект типа ЧтениеXML.
//  Имя      - имя узла, до конца которого пропускаем элементы.
//
Процедура одПропустить(Объект, Имя="")

	КоличествоВложений = 0; // Количество одноименных вложений.

	Если Имя = "" Тогда
		
		Имя = Объект.ЛокальноеИмя;
		
	КонецЕсли; 
	
	Пока Объект.Прочитать() Цикл
		
		Если Объект.ЛокальноеИмя <> Имя Тогда
			Продолжить;
		КонецЕсли;
		
		ТипУзла = Объект.ТипУзла;
			
		Если ТипУзла = ТипУзлаXMLКонецЭлемента Тогда
				
			Если КоличествоВложений = 0 Тогда
					
				Прервать;
					
			Иначе
					
				КоличествоВложений = КоличествоВложений - 1;
					
			КонецЕсли;
				
		ИначеЕсли ТипУзла = ТипУзлаXMLНачалоЭлемента Тогда
				
			КоличествоВложений = КоличествоВложений + 1;
				
		КонецЕсли;
					
	КонецЦикла;
	
КонецПроцедуры

// Читает текст элемента и приводит значение к указанному типу.
//
// Параметры:
//  Объект           - объект типа ЧтениеXML, из которого осуществляется чтение.
//  Тип              - тип получаемого значения.
//  ИскатьПоСвойству - для ссылочных типов может быть указано свойство, по которому
//                     следует искать объект: "Код", "Наименование", <ИмяРеквизита>, "Имя" (предопределенного значения).
//
// Возвращаемое значение:
//  Значение xml-элемента, приведенное к соответствующему типу.
//
Функция одЗначениеЭлемента(Объект, Тип, ИскатьПоСвойству = "", ОбрезатьСтрокуСправа = Истина)

	Значение = "";
	Имя      = Объект.ЛокальноеИмя;

	Пока Объект.Прочитать() Цикл
		
		ТипУзла = Объект.ТипУзла;
		
		Если ТипУзла = ТипУзлаXMLТекст Тогда
			
			Значение = Объект.Значение;
			
			Если ОбрезатьСтрокуСправа Тогда
				
				Значение = СокрП(Значение);
				
			КонецЕсли;
						
		ИначеЕсли (Объект.ЛокальноеИмя = Имя) И (ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		Иначе
			
			Возврат Неопределено;
			
		КонецЕсли;
		
	КонецЦикла;

	
	Если (Тип = ТипСтрока)
		ИЛИ (Тип = ТипБулево)
		ИЛИ (Тип = ТипЧисло)
		ИЛИ (Тип = ТипДата)
		ИЛИ (Тип = ТипХранилищеЗначения)
		ИЛИ (Тип = ТипУникальныйИдентификатор)
		ИЛИ (Тип = ТипВидДвиженияНакопления)
		ИЛИ (Тип = ТипВидСчета) Тогда
		
		Возврат XMLЗначение(Тип, Значение);
		
	ИначеЕсли (Тип = ТипОписаниеТипов) Тогда
		
		Возврат ОписаниеТиповИзJSON(Значение);
		
	Иначе
		
		Возврат одПолучитьЗначениеПоСтроке(Значение, Тип, ИскатьПоСвойству);
		
	КонецЕсли;
	
КонецФункции

#КонецОбласти

#Область ПроцедурыИФункцииРаботыСФайломОбмена

// Сохраняет в файл указанный xml-узел.
//
// Параметры:
//  Узел           - xml-узел, сохраняемый в файл.
//
Процедура ЗаписатьВФайл(Узел)

	Если ТипЗнч(Узел) <> ТипСтрока Тогда
		ИнформацияДляЗаписиВФайл = Узел.Закрыть();
	Иначе
		ИнформацияДляЗаписиВФайл = Узел;
	КонецЕсли;
	
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		
		// ============================ {Начало: Обмен через внешнее соединение}.
		ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеВыполнитьЗагрузкуДанныхИзСтрокиXML(ИнформацияДляЗаписиВФайл);
		
		Если ОбработкаДляЗагрузкиДанных().ФлагОшибки() Тогда
			
			СтрокаСообщения = НСтр("ru = 'Ошибка в базе-корреспонденте: %1'");
			СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ОбработкаДляЗагрузкиДанных().СтрокаСообщенияОбОшибке());
			РезультатВыполненияОбменаВнешнееСоединение = Перечисления.РезультатыВыполненияОбмена[ОбработкаДляЗагрузкиДанных().РезультатВыполненияОбменаСтрокой()];
			ЗаписатьВПротоколВыполнения(СтрокаСообщения,,,,,, РезультатВыполненияОбменаВнешнееСоединение);
			ВызватьИсключение СтрокаСообщения;
			
		КонецЕсли;
		// ============================ {Окончание: Обмен через внешнее соединение}.
		
	Иначе
		
		ФайлОбмена.ЗаписатьСтроку(ИнформацияДляЗаписиВФайл);
		
	КонецЕсли;
	
КонецПроцедуры

// Открывает файл обмена, записывает заголовок файла в соответствие с форматом обмена.
//
// Параметры:
//  Нет.
//
Функция ОткрытьФайлВыгрузки()

	ФайлОбмена = Новый ЗаписьТекста;
		
	Попытка
		ФайлОбмена.Открыть(ИмяФайлаОбмена, КодировкаТекста.UTF8);
	Исключение
		ПредставлениеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Ошибка при открытии файла для записи сообщения обмена.
				|Имя файла ""%1"".
				|Описание ошибки:
				|%2'"),
			Строка(ИмяФайлаОбмена),
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ЗаписатьВПротоколВыполнения(ПредставлениеОшибки);
		Возврат "";
	КонецПопытки;
	
	СтрокаИнформацииОXML = "<?xml version=""1.0"" encoding=""UTF-8""?>";
	
	ФайлОбмена.ЗаписатьСтроку(СтрокаИнформацииОXML);

	ВременныйЗаписьXML = Новый ЗаписьXML();
	
	ВременныйЗаписьXML.УстановитьСтроку();
	
	ВременныйЗаписьXML.ЗаписатьНачалоЭлемента("ФайлОбмена");
	
	УстановитьАтрибут(ВременныйЗаписьXML, "ВерсияФормата", 				 ВерсияФорматаСообщенияОбмена());
	УстановитьАтрибут(ВременныйЗаписьXML, "ДатаВыгрузки",				 ТекущаяДатаСеанса());
	УстановитьАтрибут(ВременныйЗаписьXML, "ИмяКонфигурацииИсточника",	 Конвертация().Источник);
	УстановитьАтрибут(ВременныйЗаписьXML, "ВерсияКонфигурацииИсточника", Конвертация().ВерсияКонфигурацииИсточника);
	УстановитьАтрибут(ВременныйЗаписьXML, "ИмяКонфигурацииПриемника",	 Конвертация().Приемник);
	УстановитьАтрибут(ВременныйЗаписьXML, "ИдПравилКонвертации",		 Конвертация().Ид);
	
	ВременныйЗаписьXML.ЗаписатьКонецЭлемента();
	
	Стр = ВременныйЗаписьXML.Закрыть();
	
	Стр = СтрЗаменить(Стр, "/>", ">");
	
	ФайлОбмена.ЗаписатьСтроку(Стр);
	
	Возврат СтрокаИнформацииОXML + Символы.ПС + Стр;
	
КонецФункции

// Закрывает файл обмена
//
// Параметры:
//  Нет.
//
Процедура ЗакрытьФайл()
	
	ФайлОбмена.ЗаписатьСтроку("</ФайлОбмена>");
	ФайлОбмена.Закрыть();
	
КонецПроцедуры

#КонецОбласти

#Область ПроцедурыИФункцииРаботыСПротоколомОбмена

// Возвращает объект типа структура, содержащий все возможные поля
// записи протокола выполнения (сообщения об ошибках и т.п.).
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  Структура - объект типа структура
//
Функция ЗаписьПротоколаОбмена(КСообщенияОбОшибках = "", Знач СтрокаОшибки = "")

	СтруктураОшибки = Новый Структура(
		"ИмяПКО,
		|ИмяПОД,
		|Нпп,
		|ГНпп,
		|Источник,
		|ТипОбъекта,
		|Свойство,
		|Значение,
		|ТипЗначения,
		|ПКО,
		|ПКС,
		|ПКГС,
		|ПВД,
		|ПОД,
		|Объект,
		|СвойствоПриемника,
		|КонвертируемоеЗначение,
		|Обработчик,
		|ОписаниеОшибки,
		|ПозицияМодуля,
		|Текст,
		|КСообщенияОбОшибках,
		|УзелПланаОбмена");
	
	СтрокаМодуля = ОтделитьРазделителем(СтрокаОшибки, "{");
	Если ПустаяСтрока(СтрокаОшибки) Тогда
		ОписаниеОшибки = СокрЛП(ОтделитьРазделителем(СтрокаМодуля, "}:"));
	Иначе
		ОписаниеОшибки = СтрокаОшибки;
		СтрокаМодуля   = "{" + СтрокаМодуля;
	КонецЕсли;
	
	Если ОписаниеОшибки <> "" Тогда
		СтруктураОшибки.ОписаниеОшибки = ОписаниеОшибки;
		СтруктураОшибки.ПозицияМодуля  = СтрокаМодуля;
	КонецЕсли;
	
	Если СтруктураОшибки.КСообщенияОбОшибках <> "" Тогда
		
		СтруктураОшибки.КСообщенияОбОшибках = КСообщенияОбОшибках;
		
	КонецЕсли;
	
	Возврат СтруктураОшибки;
	
КонецФункции 

Процедура ИнициализироватьВедениеПротоколаОбмена()
	
	Если ПустаяСтрока(ИмяФайлаПротоколаОбмена) Тогда
		
		ФайлПротоколаДанных = Неопределено;
		ФлагКомментироватьОбработкуОбъектов = ВыводВОкноСообщенийИнформационныхСообщений;		
		Возврат;
		
	Иначе	
		
		ФлагКомментироватьОбработкуОбъектов = ВыводВПротоколИнформационныхСообщений ИЛИ ВыводВОкноСообщенийИнформационныхСообщений;		
		
	КонецЕсли;
	
	// Попытка записи в файл протокола обмена.
	Попытка
		ФайлПротоколаДанных = Новый ЗаписьТекста(ИмяФайлаПротоколаОбмена, КодировкаТекста.ANSI, , ДописыватьДанныеВПротоколОбмена);
	Исключение
		ФайлПротоколаДанных = Неопределено;
		СтрокаСообщения = НСтр("ru = 'Ошибка при попытке записи в файл протокола данных: %1. Описание ошибки: %2'",
			ОбщегоНазначения.КодОсновногоЯзыка());
		СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ИмяФайлаПротоколаОбмена,
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ЗаписьЖурналаРегистрацииОбменДанными(СтрокаСообщения, УровеньЖурналаРегистрации.Предупреждение);
	КонецПопытки;
	
КонецПроцедуры

Процедура ЗавершитьВедениеПротоколаОбмена()
	
	Если ФайлПротоколаДанных <> Неопределено Тогда
		
		ФайлПротоколаДанных.Закрыть();
				
	КонецЕсли;	
	
	ФайлПротоколаДанных = Неопределено;
	
КонецПроцедуры

Процедура УстановитьРезультатВыполненияОбмена(РезультатВыполненияОбмена)
	
	ИндексТекущегоРезультата = ПриоритетыРезультатовОбмена().Найти(РезультатВыполненияОбмена());
	ИндексНовогоРезультата   = ПриоритетыРезультатовОбмена().Найти(РезультатВыполненияОбмена);
	
	Если ИндексТекущегоРезультата = Неопределено Тогда
		ИндексТекущегоРезультата = 100
	КонецЕсли;
	
	Если ИндексНовогоРезультата = Неопределено Тогда
		ИндексНовогоРезультата = 100
	КонецЕсли;
	
	Если ИндексНовогоРезультата < ИндексТекущегоРезультата Тогда
		
		ПолеРезультатВыполненияОбмена = РезультатВыполненияОбмена;
		
	КонецЕсли;
	
КонецПроцедуры

Функция РезультатВыполненияОбменаОшибка(РезультатВыполненияОбмена)
	
	Возврат РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка
		ИЛИ РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
	
КонецФункции

Функция РезультатВыполненияОбменаПредупреждение(РезультатВыполненияОбмена)
	
	Возврат РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями
		ИЛИ РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято;
	
КонецФункции

// Сохраняет в протокол выполнения (или выводит на экран) сообщения указанной структуры.
//
// Параметры:
//  Код               - Число - код сообщения.
//  СтруктураЗаписи   - Структура - структура записи протокола.
//  ВзвестиФлагОшибок - если истина, то - это сообщение об ошибке. Взводится ФлагОшибки.
// 
Функция ЗаписатьВПротоколВыполнения(Код = "",
									СтруктураЗаписи=Неопределено,
									ВзвестиФлагОшибок=Истина,
									Уровень=0,
									Выравнивание=22,
									БезусловнаяЗаписьВПротоколОбмена = Ложь,
									Знач РезультатВыполненияОбмена = Неопределено) Экспорт
	//
	Отступ = "";
	Для Сч = 0 По Уровень-1 Цикл
		Отступ = Отступ + Символы.Таб;
	КонецЦикла; 
	
	Если ТипЗнч(Код) = ТипЧисло Тогда
		
		Если СообщенияОбОшибках = Неопределено Тогда
			ИнициализацияСообщений();
		КонецЕсли;
		
		Стр = СообщенияОбОшибках[Код];
		
	Иначе
		
		Стр = Строка(Код);
		
	КонецЕсли;

	Стр = Отступ + Стр;
	
	Если СтруктураЗаписи <> Неопределено Тогда
		
		Для каждого Поле Из СтруктураЗаписи Цикл
			
			Значение = Поле.Значение;
			Если Значение = Неопределено Тогда
				Продолжить;
			КонецЕсли; 
			Ключ = Поле.Ключ;
			Стр  = Стр + Символы.ПС + Отступ + Символы.Таб + одДополнитьСтроку(Ключ, Выравнивание) + " =  " + Строка(Значение);
			
		КонецЦикла;
		
	КонецЕсли;
	
	ПолеСтрокаСообщенияОбОшибке = Стр;
	
	Если ВзвестиФлагОшибок Тогда
		
		УстановитьФлагОшибки();
		
		РезультатВыполненияОбмена = ?(РезультатВыполненияОбмена = Неопределено,
										Перечисления.РезультатыВыполненияОбмена.Ошибка,
										РезультатВыполненияОбмена);
		//
	КонецЕсли;
	
	УстановитьРезультатВыполненияОбмена(РезультатВыполненияОбмена);
	
	Если ФайлПротоколаДанных <> Неопределено Тогда
		
		Если ВзвестиФлагОшибок Тогда
			
			ФайлПротоколаДанных.ЗаписатьСтроку(Символы.ПС + "Ошибка.");
			
		КонецЕсли;
		
		Если ВзвестиФлагОшибок ИЛИ БезусловнаяЗаписьВПротоколОбмена ИЛИ ВыводВПротоколИнформационныхСообщений Тогда
			
			ФайлПротоколаДанных.ЗаписатьСтроку(Символы.ПС + СтрокаСообщенияОбОшибке());
		
		КонецЕсли;
		
	КонецЕсли;
	
	Если РезультатВыполненияОбменаОшибка(РезультатВыполненияОбмена) Тогда
		
		УровеньЖР = УровеньЖурналаРегистрации.Ошибка;
		
	ИначеЕсли РезультатВыполненияОбменаПредупреждение(РезультатВыполненияОбмена) Тогда
		
		УровеньЖР = УровеньЖурналаРегистрации.Предупреждение;
		
	Иначе
		
		УровеньЖР = УровеньЖурналаРегистрации.Информация;
		
	КонецЕсли;
	
	// Фиксируем событие в журнале регистрации.
	СтрокаСообщенияОбОшибке = СтрокаСообщенияОбОшибке();
	ЗаписьЖурналаРегистрацииОбменДанными(СтрокаСообщенияОбОшибке, УровеньЖР);
	
	ЗаписатьВРезультатыОбменаДанными = Истина;  
	Если ОбщегоНазначения.РазделениеВключено() 
		И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса") Тогда
			
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");     
		ЗаписатьВРезультатыОбменаДанными = МодульРаботаВМоделиСервиса.ИспользованиеРазделителяСеанса();
		
	КонецЕсли;
	
	Если ЗаписатьВРезультатыОбменаДанными Тогда

		ПараметрыЗаписи = Новый Структура("ПроблемныйОбъект, ТипПроблемы");
		ПараметрыЗаписи.Вставить("УзелИнформационнойБазы", УзелДляОбмена);
		ПараметрыЗаписи.Вставить("Причина", СтрокаСообщенияОбОшибке);
		
		Если ЗначениеЗаполнено(СсылкаДляПереходаПриВозникновенииОшибки) Тогда
			
			ПараметрыЗаписи.ПроблемныйОбъект = СсылкаДляПереходаПриВозникновенииОшибки;
			
		КонецЕсли;
		
		Если РежимОбмена = "Выгрузка" Тогда
			
			ПараметрыЗаписи.ТипПроблемы = Перечисления.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриОтправкеДанных;
			
		ИначеЕсли РежимОбмена = "Загрузка" Тогда
			
			ПараметрыЗаписи.ТипПроблемы = Перечисления.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриПолученииДанных;
			
		КонецЕсли;
		
		РегистрыСведений.РезультатыОбменаДанными.ДобавитьЗаписьОРезультатахОбмена(ПараметрыЗаписи);
	
	КонецЕсли;
	
	Возврат СтрокаСообщенияОбОшибке();
	
КонецФункции

Функция ЗаписатьИнформациюОбОшибкеВПротокол(КСообщенияОбОшибках, СтрокаОшибки, Объект, ТипОбъекта = Неопределено)
	
	ЗП         = ЗаписьПротоколаОбмена(КСообщенияОбОшибках, СтрокаОшибки);
	ЗП.Объект  = Объект;
	
	Если ТипОбъекта <> Неопределено Тогда
		ЗП.ТипОбъекта     = ТипОбъекта;
	КонецЕсли;	
		
	СтрокаОшибки = ЗаписатьВПротоколВыполнения(КСообщенияОбОшибках, ЗП);	
	
	Возврат СтрокаОшибки;
	
КонецФункции

Процедура ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(КСообщенияОбОшибках, СтрокаОшибки, ИмяПравилаОчисткиДанных, Объект = "", ИмяОбработчика = "")
	
	ЗП                        = ЗаписьПротоколаОбмена(КСообщенияОбОшибках, СтрокаОшибки);
	ЗП.ПОД                    = ИмяПравилаОчисткиДанных;
	
	Если Объект <> "" Тогда
		ЗП.Объект                 = Строка(Объект) + "  (" + ТипЗнч(Объект) + ")";
	КонецЕсли;
	
	Если ИмяОбработчика <> "" Тогда
		ЗП.Обработчик             = ИмяОбработчика;
	КонецЕсли;
	
	СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КСообщенияОбОшибках, ЗП);
	
	Если Не ПродолжитьПриОшибке Тогда
		ВызватьИсключение СтрокаСообщенияОбОшибке;
	КонецЕсли;
	
КонецПроцедуры

Процедура ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(КСообщенияОбОшибках, СтрокаОшибки, ИмяПравила, Источник = "", 
	ТипОбъекта, Объект = Неопределено, ИмяОбработчика)
	
	ЗП                        = ЗаписьПротоколаОбмена(КСообщенияОбОшибках, СтрокаОшибки);
	ЗП.ИмяПКО                 = ИмяПравила;
	ЗП.ТипОбъекта             = ТипОбъекта;
	ЗП.Обработчик             = ИмяОбработчика;
						
	Если Не ПустаяСтрока(Источник) Тогда
							
		ЗП.Источник           = Источник;
							
	КонецЕсли;
						
	Если Объект <> Неопределено Тогда
	
		ЗП.Объект                 = Строка(Объект);
		
	КонецЕсли;
	
	СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КСообщенияОбОшибках, ЗП);
	
	Если Не ПродолжитьПриОшибке Тогда
		ВызватьИсключение СтрокаСообщенияОбОшибке;
	КонецЕсли;
		
КонецПроцедуры

Процедура ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(КСообщенияОбОшибках, СтрокаОшибки, ПКО, Источник, ИмяОбработчика)
	
	ЗП                        = ЗаписьПротоколаОбмена(КСообщенияОбОшибках, СтрокаОшибки);
	ЗП.ПКО                    = ПКО.Имя + "  (" + ПКО.Наименование + ")";
	
	Попытка
		ЗП.Объект                 = Строка(Источник) + "  (" + ТипЗнч(Источник) + ")";
	Исключение
		ЗП.Объект                 = "(" + ТипЗнч(Источник) + ")";
	КонецПопытки;
	
	ЗП.Обработчик             = ИмяОбработчика;
	
	СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КСообщенияОбОшибках, ЗП);
	
	Если Не ПродолжитьПриОшибке Тогда
		ВызватьИсключение СтрокаСообщенияОбОшибке;
	КонецЕсли;
		
КонецПроцедуры

Процедура ЗаписатьИнформациюОбОшибкеОбработчикиПКС(КСообщенияОбОшибках, СтрокаОшибки, ПКО, ПКС, Источник = "", 
	ИмяОбработчика = "", Значение = Неопределено)
	
	ЗП                        = ЗаписьПротоколаОбмена(КСообщенияОбОшибках, СтрокаОшибки);
	ЗП.ПКО                    = ПКО.Имя + "  (" + ПКО.Наименование + ")";
	ЗП.ПКС                    = ПКС.Имя + "  (" + ПКС.Наименование + ")";
	
	Попытка
		ЗП.Объект                 = Строка(Источник) + "  (" + ТипЗнч(Источник) + ")";
	Исключение
		ЗП.Объект                 = "(" + ТипЗнч(Источник) + ")";
	КонецПопытки;
	
	ЗП.СвойствоПриемника      = ПКС.Приемник + "  (" + ПКС.ТипПриемника + ")";
	
	Если ИмяОбработчика <> "" Тогда
		ЗП.Обработчик         = ИмяОбработчика;
	КонецЕсли;
	
	Если Значение <> Неопределено Тогда
		ЗП.КонвертируемоеЗначение = Строка(Значение) + "  (" + ТипЗнч(Значение) + ")";
	КонецЕсли;
	
	СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КСообщенияОбОшибках, ЗП);
	
	Если Не ПродолжитьПриОшибке Тогда
		ВызватьИсключение СтрокаСообщенияОбОшибке;
	КонецЕсли;
		
КонецПроцедуры	

Процедура ЗаписатьИнформациюОбОшибкеОбработчикиПВД(КСообщенияОбОшибках, СтрокаОшибки, ИмяПравила, ИмяОбработчика, Объект = Неопределено)
	
	ЗП                        = ЗаписьПротоколаОбмена(КСообщенияОбОшибках, СтрокаОшибки);
	ЗП.ПВД                    = ИмяПравила;
	
	Если Объект <> Неопределено Тогда
		ЗП.Объект                 = Строка(Объект) + "  (" + ТипЗнч(Объект) + ")";
	КонецЕсли;
	
	ЗП.Обработчик             = ИмяОбработчика;
	
	СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КСообщенияОбОшибках, ЗП);
	
	Если Не ПродолжитьПриОшибке Тогда
		ВызватьИсключение СтрокаСообщенияОбОшибке;
	КонецЕсли;
	
КонецПроцедуры

Функция ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(КСообщенияОбОшибках, СтрокаОшибки, ИмяОбработчика)
	
	ЗП                        = ЗаписьПротоколаОбмена(КСообщенияОбОшибках, СтрокаОшибки);
	ЗП.Обработчик             = ИмяОбработчика;
	СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КСообщенияОбОшибках, ЗП);
	Возврат СтрокаСообщенияОбОшибке;
	
КонецФункции

#КонецОбласти

#Область ОписаниеТиповКоллекций

// Возвращаемое значение:
//   ТаблицаЗначений - коллекция правил конвертации данных:
//     * Имя - Строка
//     * Наименование - Строка
//     * Порядок - Число
//     * СинхронизироватьПоИдентификатору - Булево
//     * НеСоздаватьЕслиНеНайден - Булево
//     * НеВыгружатьОбъектыСвойствПоСсылкам - Булево
//     * ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли - Булево
//     * ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD - Булево
//     * НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике - Булево
//     * ИспользоватьБыстрыйПоискПриЗагрузке - Булево
//     * ГенерироватьНовыйНомерИлиКодЕслиНеУказан - Булево
//     * МаленькоеКоличествоОбъектов - Булево
//     * КоличествоОбращенийДляВыгрузкиСсылки - Число
//     * КоличествоЭлементовВИБ - Число
//     * СпособВыгрузки - Произвольный
//     * Источник - Произвольный
//     * Приемник - Произвольный
//     * ТипИсточника - Строка
//     * ТипПриемника - Строка
//     * ПередВыгрузкой - Произвольный
//     * ИмяОбработчикаПередВыгрузкой - Строка
//     * ПриВыгрузке - Произвольный
//     * ИмяОбработчикаПриВыгрузке - Строка
//     * ПослеВыгрузки - Произвольный
//     * ИмяОбработчикаПослеВыгрузки - Строка
//     * ПослеВыгрузкиВФайл - Произвольный
//     * ИмяОбработчикаПослеВыгрузкиВФайл - Строка
//     * ЕстьОбработчикПередВыгрузкой - Булево
//     * ЕстьОбработчикПриВыгрузке - Булево
//     * ЕстьОбработчикПослеВыгрузки - Булево
//     * ЕстьОбработчикПослеВыгрузкиВФайл - Булево
//     * ПередЗагрузкой - Произвольный
//     * ИмяОбработчикаПередЗагрузкой - Строка
//     * ПриЗагрузке - Произвольный
//     * ИмяОбработчикаПриЗагрузке - Строка
//     * ПослеЗагрузки - Произвольный
//     * ИмяОбработчикаПослеЗагрузки - Строка
//     * ПоследовательностьПолейПоиска - Произвольный
//     * ИмяОбработчикаПоследовательностьПолейПоиска - Строка
//     * ПоискПоТабличнымЧастям - см. КоллекцияПоискПоТабличнымЧастям
//     * ПриоритетОбъектовОбмена - Произвольный
//     * ЕстьОбработчикПередЗагрузкой - Булево
//     * ЕстьОбработчикПриЗагрузке - Булево
//     * ЕстьОбработчикПослеЗагрузки - Булево
//     * ЕстьОбработчикПоследовательностьПолейПоиска - Булево
//     * Свойства - см. КоллекцияПравилаКонвертацииСвойств
//     * СвойстваПоиска - см. КоллекцияПравилаКонвертацииСвойств
//     * СвойстваОтключенные - см. КоллекцияПравилаКонвертацииСвойств
//     * ЗначенияПредопределенныхДанных - Соответствие
//     * ЗначенияПредопределенныхДанныхПрочитанные - Структура
//     * Выгруженные - ТаблицаЗначений
//     * ВыгружатьПредставлениеИсточника - Булево
//     * НеЗамещать - Булево
//     * ЗапоминатьВыгруженные - Булево
//     * ВсеОбъектыВыгружены - Булево
//     * ПоляПоиска - Строка
//     * ПоляТаблицы - Строка
// 
Функция КоллекцияПравилаКонвертации()
	
	Возврат ТаблицаПравилКонвертации;
	
КонецФункции

// Возвращаемое значение:
//   ТаблицаЗначений - коллекция правил поиска по табличным частям:
//     * ИмяЭлемента - Произвольный
//     * МассивКлючевыхПолейПоиска - Массив из Произвольный
//     * КлючевыеПоляПоиска - Произвольный
//     * Валидное - Булево
// 
Функция КоллекцияПоискПоТабличнымЧастям()
	
	ПоискПоТабличнымЧастям = Новый ТаблицаЗначений;
	ПоискПоТабличнымЧастям.Колонки.Добавить("ИмяЭлемента");
	ПоискПоТабличнымЧастям.Колонки.Добавить("МассивКлючевыхПолейПоиска");
	ПоискПоТабличнымЧастям.Колонки.Добавить("КлючевыеПоляПоиска");
	ПоискПоТабличнымЧастям.Колонки.Добавить("Валидное", одОписаниеТипа("Булево"));
	
	Возврат ПоискПоТабличнымЧастям;
	
КонецФункции

// Возвращаемое значение:
//   ТаблицаЗначений - коллекция правил конвертации свойств данных:
//     * Имя - Строка
//     * Наименование - Строка
//     * Порядок - Число
//     * ЭтоГруппа - Булево
//     * ЭтоПолеПоиска - Булево
//     * ПравилаГруппы - см. КоллекцияПравилаКонвертацииСвойств
//     * ПравилаГруппыОтключенные - Произвольный
//     * ВидИсточника - Произвольный
//     * ВидПриемника - Произвольный
//     * УпрощеннаяВыгрузкаСвойства - Булево
//     * НуженУзелXMLПриВыгрузке - Булево
//     * НуженУзелXMLПриВыгрузкеГруппы - Булево
//     * ТипИсточника - Строка
//     * ТипПриемника - Строка
//     * Источник - Произвольный
//     * Приемник - Произвольный
//     * ПравилоКонвертации - Произвольный
//     * ПолучитьИзВходящихДанных - Булево
//     * НеЗамещать - Булево
//     * ЭтоОбязательноеСвойство - Булево
//     * ПередВыгрузкой - Произвольный
//     * ИмяОбработчикаПередВыгрузкой - Произвольный
//     * ПриВыгрузке - Произвольный
//     * ИмяОбработчикаПриВыгрузке - Произвольный
//     * ПослеВыгрузки - Произвольный
//     * ИмяОбработчикаПослеВыгрузки - Произвольный
//     * ПередОбработкойВыгрузки - Произвольный
//     * ИмяОбработчикаПередОбработкойВыгрузки - Произвольный
//     * ПослеОбработкиВыгрузки - Произвольный
//     * ИмяОбработчикаПослеОбработкиВыгрузки - Произвольный
//     * ЕстьОбработчикПередВыгрузкой - Булево
//     * ЕстьОбработчикПриВыгрузке - Булево
//     * ЕстьОбработчикПослеВыгрузки - Булево
//     * ЕстьОбработчикПередОбработкойВыгрузки - Булево
//     * ЕстьОбработчикПослеОбработкиВыгрузки - Булево
//     * ПриводитьКДлине - Число
//     * ИмяПараметраДляПередачи - Строка
//     * ПоискПоДатеНаРавенство - Булево
//     * ВыгружатьГруппуЧерезФайл - Булево
//     * СтрокаПолейПоиска - Произвольный
// 
Функция КоллекцияПравилаКонвертацииСвойств()
	
	Возврат ТаблицаПравилКонвертацииСвойств;
	
КонецФункции

// Возвращаемое значение:
//   ТаблицаЗначений - коллекция правил выгрузки данных:
//     * Включить - Булево
//     * Имя - Произвольный
//     * Наименование - Произвольный
//     * Порядок - Произвольный
//     * СпособОтбораДанных - Произвольный
//     * ОбъектВыборки - Произвольный
//     * ОбъектВыборкиМетаданные - Произвольный
//     * ПравилоКонвертации - Произвольный
//     * ПередОбработкой - Произвольный
//     * ИмяОбработчикаПередОбработкой - Произвольный
//     * ПослеОбработки - Произвольный
//     * ИмяОбработчикаПослеОбработки - Произвольный
//     * ПередВыгрузкой - Произвольный
//     * ИмяОбработчикаПередВыгрузкой - Произвольный
//     * ПослеВыгрузки - Произвольный
//     * ИмяОбработчикаПослеВыгрузки - Произвольный
//     * ИспользоватьОтбор - Булево
//     * НастройкиПостроителя - Произвольный
//     * ИмяОбъектаДляЗапроса - Произвольный
//     * ИмяОбъектаДляЗапросаРегистра - Произвольный
//     * ИмяТипаПриемника - Произвольный
//     * НеВыгружатьОбъектыСозданныеВБазеПриемнике - Булево
//     * СсылкаНаУзелОбмена - Произвольный
//     * СинхронизироватьПоИдентификатору - Булево
// 
Функция КоллекцияПравилаВыгрузкиДанных()
	
	Возврат ТаблицаПравилВыгрузки;

КонецФункции

// Возвращаемое значение:
//   ДеревоЗначений - коллекция правил очистки данных:
//     * Включить -  Булево
//     * ЭтоГруппа - Булево
//     * Имя - Строка
//     * Наименование - Строка
//     * Порядок - Число
//     * СпособОтбораДанных - Произвольный
//     * ОбъектВыборки - Произвольный
//     * УдалятьЗаПериод - Произвольный
//     * Непосредственно - Булево
//     * ПередОбработкой - Произвольный
//     * ИмяОбработчикаПередОбработкой - Произвольный
//     * ПослеОбработки - Произвольный
//     * ИмяОбработчикаПослеОбработки - Произвольный
//     * ПередУдалением - Произвольный
//     * ИмяОбработчикаПередУдалением - Произвольный
// 
Функция КоллекцияПравилаОчисткиДанных()

	Возврат ТаблицаПравилОчистки;

КонецФункции

// Возвращаемое значение:
//   ТаблицаЗначений:
//     * Ссылка - ЛюбаяСсылка - ссылка на выгружаемый объект.
//
Функция КоллекцияСтекВызововВыгрузкиДанных()
	
	Возврат СтекВызововВыгрузкиДанных;
	
КонецФункции

#КонецОбласти

#Область ПроцедурыЗагрузкиПравилОбмена

// Осуществляет загрузку правила конвертации группы свойств.
//
// Параметры:
//   ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//   ТаблицаСвойств - см. КоллекцияПравилаКонвертацииСвойств
//   СвойстваОтключенные - см. КоллекцияПравилаКонвертацииСвойств
//   СинхронизироватьПоИдентификатору - Булево - Истина, если синхронизация выполняется по идентификатору.
//   ИмяПКО - Строка - имя правила конвертации.
//
Процедура ЗагрузитьПКГС(ПравилаОбмена, ТаблицаСвойств, СвойстваОтключенные, СинхронизироватьПоИдентификатору, ИмяПКО = "")
	
	ЭтоПолеОтключено = одАтрибут(ПравилаОбмена, ТипБулево, "Отключить");
	
	Если ЭтоПолеОтключено Тогда
		
		НоваяСтрока = СвойстваОтключенные.Добавить();
		
	Иначе
		
		НоваяСтрока = ТаблицаСвойств.Добавить();
		
	КонецЕсли;
	
	НоваяСтрока.ЭтоГруппа     = Истина;
	
	НоваяСтрока.ПравилаГруппы            = ТаблицаПравилКонвертацииСвойств.Скопировать();
	НоваяСтрока.ПравилаГруппыОтключенные = ТаблицаПравилКонвертацииСвойств.Скопировать();
	
	// Значения по умолчанию
	НоваяСтрока.НеЗамещать               = Ложь;
	НоваяСтрока.ПолучитьИзВходящихДанных = Ложь;
	НоваяСтрока.УпрощеннаяВыгрузкаСвойства = Ложь;
	
	СтрокаПолейПоиска = "";
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Источник" Тогда
			НоваяСтрока.Источник		= одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
			НоваяСтрока.ВидИсточника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Вид");
			НоваяСтрока.ТипИсточника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Тип");
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "Приемник" Тогда
			НоваяСтрока.Приемник		= одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
			НоваяСтрока.ВидПриемника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Вид");
			НоваяСтрока.ТипПриемника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Тип");
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "Свойство" Тогда
			
			РодительПКС = ?(ЗначениеЗаполнено(НоваяСтрока.Источник), "_" + НоваяСтрока.Источник, "_" + НоваяСтрока.Приемник);
			
			СвойстваПКО = Новый Структура;
			СвойстваПКО.Вставить("ИмяПКО", ИмяПКО);
			СвойстваПКО.Вставить("ИмяРодителя", РодительПКС);
			СвойстваПКО.Вставить("СинхронизироватьПоИдентификатору", СинхронизироватьПоИдентификатору);
			
			ЗагрузитьПКС(ПравилаОбмена, НоваяСтрока.ПравилаГруппы, НоваяСтрока.ПравилаГруппыОтключенные, СвойстваПКО, СтрокаПолейПоиска);

		ИначеЕсли ИмяУзла = "ПередОбработкойВыгрузки" Тогда
			НоваяСтрока.ПередОбработкойВыгрузки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПередОбработкойВыгрузки = Не ПустаяСтрока(НоваяСтрока.ПередОбработкойВыгрузки);
			
		ИначеЕсли ИмяУзла = "ПослеОбработкиВыгрузки" Тогда
			НоваяСтрока.ПослеОбработкиВыгрузки	= одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПослеОбработкиВыгрузки = Не ПустаяСтрока(НоваяСтрока.ПослеОбработкиВыгрузки);
			
		ИначеЕсли ИмяУзла = "Код" Тогда
			НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "Наименование" Тогда
			НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "Порядок" Тогда
			НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, ТипЧисло);
			
		ИначеЕсли ИмяУзла = "НеЗамещать" Тогда
			НоваяСтрока.НеЗамещать = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли ИмяУзла = "КодПравилаКонвертации" Тогда
			НоваяСтрока.ПравилоКонвертации = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "ПередВыгрузкой" Тогда
			НоваяСтрока.ПередВыгрузкой = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПередВыгрузкой = Не ПустаяСтрока(НоваяСтрока.ПередВыгрузкой);
			
		ИначеЕсли ИмяУзла = "ПриВыгрузке" Тогда
			НоваяСтрока.ПриВыгрузке = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПриВыгрузке    = Не ПустаяСтрока(НоваяСтрока.ПриВыгрузке);
			
		ИначеЕсли ИмяУзла = "ПослеВыгрузки" Тогда
			НоваяСтрока.ПослеВыгрузки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПослеВыгрузки  = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузки);
			
		ИначеЕсли ИмяУзла = "ВыгружатьГруппуЧерезФайл" Тогда
			НоваяСтрока.ВыгружатьГруппуЧерезФайл = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли ИмяУзла = "ПолучитьИзВходящихДанных" Тогда
			НоваяСтрока.ПолучитьИзВходящихДанных = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли (ИмяУзла = "Группа") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если НоваяСтрока.ЕстьОбработчикПередОбработкойВыгрузки Тогда
		
		ИмяОбработчика = "ПКГС_[ИмяПКО][ИмяСвойстваПКС]_ПередОбработкойВыгрузки_[ИмяПКГС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКГС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));
		НоваяСтрока.ИмяОбработчикаПередОбработкойВыгрузки = ИмяОбработчика;
		
	КонецЕсли;
	
	Если НоваяСтрока.ЕстьОбработчикПослеОбработкиВыгрузки Тогда
		
		ИмяОбработчика = "ПКГС_[ИмяПКО][ИмяСвойстваПКС]_ПослеОбработкиВыгрузки_[ИмяПКГС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКГС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));
		НоваяСтрока.ИмяОбработчикаПослеОбработкиВыгрузки = ИмяОбработчика;
		
	КонецЕсли;
	
	Если НоваяСтрока.ЕстьОбработчикПередВыгрузкой Тогда
		
		ИмяОбработчика = "ПКГС_[ИмяПКО][ИмяСвойстваПКС]_ПередВыгрузкойСвойства_[ИмяПКГС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКГС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));
		НоваяСтрока.ИмяОбработчикаПередВыгрузкой = ИмяОбработчика;

	КонецЕсли;
	
	Если НоваяСтрока.ЕстьОбработчикПриВыгрузке Тогда
		
		ИмяОбработчика = "ПКГС_[ИмяПКО][ИмяСвойстваПКС]_ПриВыгрузкеСвойства_[ИмяПКГС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКГС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));
		НоваяСтрока.ИмяОбработчикаПриВыгрузке = ИмяОбработчика;

	КонецЕсли;
	
	Если НоваяСтрока.ЕстьОбработчикПослеВыгрузки Тогда
		
		ИмяОбработчика = "ПКГС_[ИмяПКО][ИмяСвойстваПКС]_ПослеВыгрузкиСвойства_[ИмяПКГС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКГС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));
		НоваяСтрока.ИмяОбработчикаПослеВыгрузки = ИмяОбработчика;
		
	КонецЕсли;
	
	НоваяСтрока.СтрокаПолейПоиска = СтрокаПолейПоиска;
	
	НоваяСтрока.НуженУзелXMLПриВыгрузке = НоваяСтрока.ЕстьОбработчикПриВыгрузке ИЛИ НоваяСтрока.ЕстьОбработчикПослеВыгрузки;
	
	НоваяСтрока.НуженУзелXMLПриВыгрузкеГруппы = НоваяСтрока.ЕстьОбработчикПослеОбработкиВыгрузки; 

КонецПроцедуры

Процедура ДобавитьПолеКСтрокеПоиска(СтрокаПолейПоиска, ИмяПоля)
	
	Если ПустаяСтрока(ИмяПоля) Тогда
		Возврат;
	КонецЕсли;
	
	Если НЕ ПустаяСтрока(СтрокаПолейПоиска) Тогда
		СтрокаПолейПоиска = СтрокаПолейПоиска + ",";
	КонецЕсли;
	
	СтрокаПолейПоиска = СтрокаПолейПоиска + ИмяПоля;
	
КонецПроцедуры

// Осуществляет загрузку правила конвертации свойств.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект, содержащий текст правил обмена.
//  ТаблицаСвойств - см. КоллекцияПравилаКонвертацииСвойств
//  СвойстваОтключенные - см. КоллекцияПравилаКонвертацииСвойств
//  СвойстваПКО - Структура - уточняющие сведения об изменяемых данных:
//    * ИмяПКО - Строка - имя ПКО.
//    * СинхронизироватьПоИдентификатору - Булево - признак использования алгоритма поиска по уникальному идентификатору.
//    * ИмяРодителя - Строка - имя родительского ПКО или ПКГС.
//  СтрокаПолейПоиска - Строка - свойства поиска ПКО.
//  ТаблицаПоиска - см. КоллекцияПравилаКонвертацииСвойств
//
Процедура ЗагрузитьПКС(ПравилаОбмена,
	ТаблицаСвойств,
	СвойстваОтключенные,
	СвойстваПКО,
	СтрокаПолейПоиска = "",
	ТаблицаПоиска = Неопределено)
	
	ИмяПКО = ?(ЗначениеЗаполнено(СвойстваПКО.ИмяПКО), СвойстваПКО.ИмяПКО, "");
	ИмяРодителя = ?(ЗначениеЗаполнено(СвойстваПКО.ИмяРодителя), СвойстваПКО.ИмяРодителя, "");
	СинхронизироватьПоИдентификатору = ?(ЗначениеЗаполнено(СвойстваПКО.СинхронизироватьПоИдентификатору),
		СвойстваПКО.СинхронизироватьПоИдентификатору, Ложь);
	
	ЭтоПолеОтключено        = одАтрибут(ПравилаОбмена, ТипБулево, "Отключить");
	ЭтоПолеПоиска           = одАтрибут(ПравилаОбмена, ТипБулево, "Поиск");
	ЭтоОбязательноеСвойство = одАтрибут(ПравилаОбмена, ТипБулево, "Обязательное");
	
	Если ЭтоПолеОтключено Тогда
		
		НоваяСтрока = СвойстваОтключенные.Добавить();
		
	ИначеЕсли ЭтоОбязательноеСвойство И ТаблицаПоиска <> Неопределено Тогда
		
		НоваяСтрока = ТаблицаПоиска.Добавить();
		
	ИначеЕсли ЭтоПолеПоиска И ТаблицаПоиска <> Неопределено Тогда
		
		НоваяСтрока = ТаблицаПоиска.Добавить();
		
	Иначе
		
		НоваяСтрока = ТаблицаСвойств.Добавить();
		
	КонецЕсли;
	
	// Значения по умолчанию
	НоваяСтрока.НеЗамещать               = Ложь;
	НоваяСтрока.ПолучитьИзВходящихДанных = Ложь;
	НоваяСтрока.ЭтоОбязательноеСвойство  = ЭтоОбязательноеСвойство;
	НоваяСтрока.ЭтоПолеПоиска            = ЭтоПолеПоиска;
		
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Источник" Тогда
			НоваяСтрока.Источник		= одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
			НоваяСтрока.ВидИсточника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Вид");
			НоваяСтрока.ТипИсточника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Тип");
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "Приемник" Тогда
			НоваяСтрока.Приемник		= одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
			НоваяСтрока.ВидПриемника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Вид");
			НоваяСтрока.ТипПриемника	= одАтрибут(ПравилаОбмена, ТипСтрока, "Тип");
			
			Если Не ЭтоПолеОтключено Тогда
				
				// Заполняем переменную "СтрокаПолейПоиска" для поиска по всем реквизитам в ТЧ для которых есть ПКС.
				ДобавитьПолеКСтрокеПоиска(СтрокаПолейПоиска, НоваяСтрока.Приемник);
				
			КонецЕсли;
			
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "Код" Тогда
			НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "Наименование" Тогда
			НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "Порядок" Тогда
			НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, ТипЧисло);
			
		ИначеЕсли ИмяУзла = "НеЗамещать" Тогда
			НоваяСтрока.НеЗамещать = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли ИмяУзла = "КодПравилаКонвертации" Тогда
			НоваяСтрока.ПравилоКонвертации = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "ПередВыгрузкой" Тогда
			НоваяСтрока.ПередВыгрузкой = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПередВыгрузкой = Не ПустаяСтрока(НоваяСтрока.ПередВыгрузкой);
			
		ИначеЕсли ИмяУзла = "ПриВыгрузке" Тогда
			НоваяСтрока.ПриВыгрузке = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПриВыгрузке    = Не ПустаяСтрока(НоваяСтрока.ПриВыгрузке);
			
		ИначеЕсли ИмяУзла = "ПослеВыгрузки" Тогда
			НоваяСтрока.ПослеВыгрузки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
	        НоваяСтрока.ЕстьОбработчикПослеВыгрузки  = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузки);
			
		ИначеЕсли ИмяУзла = "ПолучитьИзВходящихДанных" Тогда
			НоваяСтрока.ПолучитьИзВходящихДанных = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли ИмяУзла = "ПриводитьКДлине" Тогда
			НоваяСтрока.ПриводитьКДлине = одЗначениеЭлемента(ПравилаОбмена, ТипЧисло);
			
		ИначеЕсли ИмяУзла = "ИмяПараметраДляПередачи" Тогда
			НоваяСтрока.ИмяПараметраДляПередачи = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "ПоискПоДатеНаРавенство" Тогда
			НоваяСтрока.ПоискПоДатеНаРавенство = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли (ИмяУзла = "Свойство") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если НоваяСтрока.ЕстьОбработчикПередВыгрузкой Тогда
		
		ИмяОбработчика = "ПКС_[ИмяПКО][ИмяРодителя][ИмяСвойстваПКС]_ПередВыгрузкойСвойства_[ИмяПКС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяРодителя]", ИмяРодителя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));
		
		НоваяСтрока.ИмяОбработчикаПередВыгрузкой = ИмяОбработчика;
		
	КонецЕсли;
	
	Если НоваяСтрока.ЕстьОбработчикПриВыгрузке Тогда
		
		ИмяОбработчика = "ПКС_[ИмяПКО][ИмяРодителя][ИмяСвойстваПКС]_ПриВыгрузкеСвойства_[ИмяПКС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяРодителя]", ИмяРодителя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));
		
		НоваяСтрока.ИмяОбработчикаПриВыгрузке = ИмяОбработчика;
		
	КонецЕсли;
	
	Если НоваяСтрока.ЕстьОбработчикПослеВыгрузки Тогда
		
		ИмяОбработчика = "ПКС_[ИмяПКО][ИмяРодителя][ИмяСвойстваПКС]_ПослеВыгрузкиСвойства_[ИмяПКС]_[ДлинаИмениПКО]";
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", ИмяПКО);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяРодителя]", ИмяРодителя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяСвойстваПКС]", ИмяСвойстваПКС(НоваяСтрока));
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПКС]", НоваяСтрока.Имя);
		ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ДлинаИмениПКО]", СтрДлина(ИмяПКО));

		НоваяСтрока.ИмяОбработчикаПослеВыгрузки = ИмяОбработчика;
		
	КонецЕсли;
	
	НоваяСтрока.УпрощеннаяВыгрузкаСвойства = НЕ НоваяСтрока.ПолучитьИзВходящихДанных
		И НЕ НоваяСтрока.ЕстьОбработчикПередВыгрузкой
		И НЕ НоваяСтрока.ЕстьОбработчикПриВыгрузке
		И НЕ НоваяСтрока.ЕстьОбработчикПослеВыгрузки
		И ПустаяСтрока(НоваяСтрока.ПравилоКонвертации)
		И НоваяСтрока.ТипИсточника = НоваяСтрока.ТипПриемника
		И (НоваяСтрока.ТипИсточника = "Строка" ИЛИ НоваяСтрока.ТипИсточника = "Число" ИЛИ НоваяСтрока.ТипИсточника = "Булево" ИЛИ НоваяСтрока.ТипИсточника = "Дата");
		
	НоваяСтрока.НуженУзелXMLПриВыгрузке = НоваяСтрока.ЕстьОбработчикПриВыгрузке ИЛИ НоваяСтрока.ЕстьОбработчикПослеВыгрузки;
	
КонецПроцедуры

// Осуществляет загрузку правил конвертации свойств.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ТаблицаСвойств - ТаблицаЗначений - таблица значений, содержащая ПКС.
//  ТаблицаПоиска  - ТаблицаЗначений - таблица значений, содержащая ПКС (синхронизирующих).
//
Процедура ЗагрузитьСвойства(ПравилаОбмена,
							ТаблицаСвойств,
							ТаблицаПоиска,
							СвойстваОтключенные,
							Знач СинхронизироватьПоИдентификатору = Ложь,
							ИмяПКО = "")
	//
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Свойство" Тогда
			
			СвойстваПКО = Новый Структура;
			СвойстваПКО.Вставить("ИмяПКО", ИмяПКО);
			СвойстваПКО.Вставить("ИмяРодителя", "");
			СвойстваПКО.Вставить("СинхронизироватьПоИдентификатору", СинхронизироватьПоИдентификатору);
			ЗагрузитьПКС(ПравилаОбмена, ТаблицаСвойств, СвойстваОтключенные, СвойстваПКО,, ТаблицаПоиска);
			
		ИначеЕсли ИмяУзла = "Группа" Тогда
			
			ЗагрузитьПКГС(ПравилаОбмена, ТаблицаСвойств, СвойстваОтключенные, СинхронизироватьПоИдентификатору, ИмяПКО);
			
		ИначеЕсли (ИмяУзла = "Свойства") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	ТаблицаСвойств.Сортировать("Порядок");
	ТаблицаПоиска.Сортировать("Порядок");
	СвойстваОтключенные.Сортировать("Порядок");
	
КонецПроцедуры

// Осуществляет загрузку правила конвертации значений.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  Значения       - соответствие значений объекта источника - строковым
//                   представлениям объекта приемника.
//  ТипИсточника   - значение Тип - типа Тип - тип объекта источника.
//
Процедура ЗагрузитьПКЗ(ПравилаОбмена, Значения, ТипИсточника)
	
	Источник = "";
	Приемник = "";
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Источник" Тогда
			Источник = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
		ИначеЕсли ИмяУзла = "Приемник" Тогда
			Приемник = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
		ИначеЕсли (ИмяУзла = "Значение") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если Не ПустаяСтрока(Источник) Тогда
		Значения.Вставить(Источник, Приемник);
	КонецЕсли;
	
КонецПроцедуры

// Осуществляет загрузку правил конвертации значений.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  Значения       - соответствие значений объекта источника - строковым
//                   представлениям объекта приемника.
//  ТипИсточника   - значение Тип - типа Тип - тип объекта источника.
//
Процедура ЗагрузитьЗначения(ПравилаОбмена, Значения, ТипИсточника)

	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Значение" Тогда
			ЗагрузитьПКЗ(ПравилаОбмена, Значения, ТипИсточника);
		ИначеЕсли (ИмяУзла = "Значения") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Осуществляет загрузку правила конвертации объектов.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьПравилоКонвертации(ПравилаОбмена, ЗаписьXML)

	ЗаписьXML.ЗаписатьНачалоЭлемента("Правило");

	НоваяСтрока = КоллекцияПравилаКонвертации().Добавить();
	
	// Значения по умолчанию
	
	НоваяСтрока.ЗапоминатьВыгруженные = Истина;
	НоваяСтрока.НеЗамещать            = Ложь;
	НоваяСтрока.ПриоритетОбъектовОбмена = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаВыше;
	
	НоваяСтрока.ПоискПоТабличнымЧастям = КоллекцияПоискПоТабличнымЧастям();
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
				
		Если      ИмяУзла = "Код" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
			НоваяСтрока.Имя = Значение;
			
		ИначеЕсли ИмяУзла = "Наименование" Тогда
			
			НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "СинхронизироватьПоИдентификатору" Тогда
			
			НоваяСтрока.СинхронизироватьПоИдентификатору = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.СинхронизироватьПоИдентификатору);
			
		ИначеЕсли ИмяУзла = "НеСоздаватьЕслиНеНайден" Тогда
			
			НоваяСтрока.НеСоздаватьЕслиНеНайден = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);			
			
		ИначеЕсли ИмяУзла = "РегистрироватьОбъектНаУзлеОтправителе" Тогда // не поддерживается
			
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "НеВыгружатьОбъектыСвойствПоСсылкам" Тогда
			
			НоваяСтрока.НеВыгружатьОбъектыСвойствПоСсылкам = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
						
		ИначеЕсли ИмяУзла = "ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли" Тогда
			
			НоваяСтрока.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);	
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли);
			
		ИначеЕсли ИмяУзла = "ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD" Тогда
			
			НоваяСтрока.ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);	
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD);
			
		ИначеЕсли ИмяУзла = "НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике" Тогда
			
			НоваяСтрока.НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);	
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике);		
			
		ИначеЕсли ИмяУзла = "ИспользоватьБыстрыйПоискПриЗагрузке" Тогда
			
			НоваяСтрока.ИспользоватьБыстрыйПоискПриЗагрузке = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);	
			
		ИначеЕсли ИмяУзла = "ГенерироватьНовыйНомерИлиКодЕслиНеУказан" Тогда
			
			НоваяСтрока.ГенерироватьНовыйНомерИлиКодЕслиНеУказан = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.ГенерироватьНовыйНомерИлиКодЕслиНеУказан);
						
		ИначеЕсли ИмяУзла = "НеЗапоминатьВыгруженные" Тогда
			
			НоваяСтрока.ЗапоминатьВыгруженные = Не одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли ИмяУзла = "НеЗамещать" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
			НоваяСтрока.НеЗамещать = Значение;
			
		ИначеЕсли ИмяУзла = "Приемник" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
			
			НоваяСтрока.Приемник     = Значение;
			НоваяСтрока.ТипПриемника = Значение;
			
		ИначеЕсли ИмяУзла = "Источник" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
			
			НоваяСтрока.ТипИсточника = Значение;
			
			Если РежимОбмена = "Загрузка" Тогда
				
				НоваяСтрока.Источник = Значение;
				
			Иначе
				
				Если Не ПустаяСтрока(Значение) Тогда
					
					Если Не РежимЗагрузкиИнформацииОПравилахОбмена Тогда
						
						Попытка
							
							НоваяСтрока.Источник = Тип(Значение);
							
							Менеджеры[НоваяСтрока.Источник].ПКО = НоваяСтрока;
							
						Исключение
							
							ЗаписатьИнформациюОбОшибкеВПротокол(11, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
								Строка(НоваяСтрока.Источник));
							
						КонецПопытки;
					
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЕсли;
			
		// Свойства
		
		ИначеЕсли ИмяУзла = "Свойства" Тогда
		
			НоваяСтрока.Свойства            = КоллекцияПравилаКонвертацииСвойств().Скопировать();
			НоваяСтрока.СвойстваПоиска      = КоллекцияПравилаКонвертацииСвойств().Скопировать();
			НоваяСтрока.СвойстваОтключенные = КоллекцияПравилаКонвертацииСвойств().Скопировать();
			
			Если НоваяСтрока.СинхронизироватьПоИдентификатору = Истина Тогда
				
				СвойствоПоискаУИ = НоваяСтрока.СвойстваПоиска.Добавить();
				СвойствоПоискаУИ.Имя      = "{УникальныйИдентификатор}";
				СвойствоПоискаУИ.Источник = "{УникальныйИдентификатор}";
				СвойствоПоискаУИ.Приемник = "{УникальныйИдентификатор}";
				СвойствоПоискаУИ.ЭтоОбязательноеСвойство = Истина;
				
			КонецЕсли;
			
			ЗагрузитьСвойства(ПравилаОбмена, НоваяСтрока.Свойства, НоваяСтрока.СвойстваПоиска, НоваяСтрока.СвойстваОтключенные, НоваяСтрока.СинхронизироватьПоИдентификатору, НоваяСтрока.Имя);
			
		// Значения
		ИначеЕсли ИмяУзла = "Значения" Тогда
			
			ЗагрузитьЗначения(ПравилаОбмена, НоваяСтрока.ЗначенияПредопределенныхДанныхПрочитанные, НоваяСтрока.Источник);
			
		// Обработчики событий
		ИначеЕсли ИмяУзла = "ПередВыгрузкой" Тогда
		
			НоваяСтрока.ПередВыгрузкой = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПКО_[ИмяПКО]_ПередВыгрузкойОбъекта";
			НоваяСтрока.ИмяОбработчикаПередВыгрузкой = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
			НоваяСтрока.ЕстьОбработчикПередВыгрузкой = Не ПустаяСтрока(НоваяСтрока.ПередВыгрузкой);
			
		ИначеЕсли ИмяУзла = "ПриВыгрузке" Тогда
			
			НоваяСтрока.ПриВыгрузке = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПКО_[ИмяПКО]_ПриВыгрузкеОбъекта";
			НоваяСтрока.ИмяОбработчикаПриВыгрузке = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
			НоваяСтрока.ЕстьОбработчикПриВыгрузке    = Не ПустаяСтрока(НоваяСтрока.ПриВыгрузке);
			
		ИначеЕсли ИмяУзла = "ПослеВыгрузки" Тогда
			
			НоваяСтрока.ПослеВыгрузки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПКО_[ИмяПКО]_ПослеВыгрузкиОбъекта";
			НоваяСтрока.ИмяОбработчикаПослеВыгрузки = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
			НоваяСтрока.ЕстьОбработчикПослеВыгрузки  = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузки);
			
		ИначеЕсли ИмяУзла = "ПослеВыгрузкиВФайл" Тогда
			
			НоваяСтрока.ПослеВыгрузкиВФайл = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПКО_[ИмяПКО]_ПослеВыгрузкиОбъектаВФайлОбмена";
			НоваяСтрока.ИмяОбработчикаПослеВыгрузкиВФайл = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
			НоваяСтрока.ЕстьОбработчикПослеВыгрузкиВФайл  = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузкиВФайл);
			
		// Для загрузки
		
		ИначеЕсли ИмяУзла = "ПередЗагрузкой" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
			Если РежимОбмена = "Загрузка" Тогда
				
				НоваяСтрока.ПередЗагрузкой               = Значение;
				ИмяОбработчика = "ПКО_[ИмяПКО]_ПередЗагрузкойОбъекта";
				НоваяСтрока.ИмяОбработчикаПередЗагрузкой = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
				НоваяСтрока.ЕстьОбработчикПередЗагрузкой = Не ПустаяСтрока(Значение);
				
			Иначе
				
				одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ПриЗагрузке" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
			Если РежимОбмена = "Загрузка" Тогда
				
				НоваяСтрока.ПриЗагрузке               = Значение;
				ИмяОбработчика = "ПКО_[ИмяПКО]_ПриЗагрузкеОбъекта";
				НоваяСтрока.ИмяОбработчикаПриЗагрузке = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
				НоваяСтрока.ЕстьОбработчикПриЗагрузке = Не ПустаяСтрока(Значение);
				
			Иначе
				
				одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
				
			КонецЕсли; 
			
		ИначеЕсли ИмяУзла = "ПослеЗагрузки" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
			Если РежимОбмена = "Загрузка" Тогда
				
				НоваяСтрока.ПослеЗагрузки               = Значение;
				ИмяОбработчика = "ПКО_[ИмяПКО]_ПослеЗагрузкиОбъекта";
				НоваяСтрока.ИмяОбработчикаПослеЗагрузки = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
				НоваяСтрока.ЕстьОбработчикПослеЗагрузки = Не ПустаяСтрока(Значение);
				
			Иначе
				
				одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ПоследовательностьПолейПоиска" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.ЕстьОбработчикПоследовательностьПолейПоиска = Не ПустаяСтрока(Значение);
			
			Если РежимОбмена = "Загрузка" Тогда
				
				НоваяСтрока.ПоследовательностьПолейПоиска = Значение;
				ИмяОбработчика = "ПКО_[ИмяПКО]_ПоследовательностьПолейПоиска";
				НоваяСтрока.ИмяОбработчикаПоследовательностьПолейПоиска = СтрЗаменить(ИмяОбработчика, "[ИмяПКО]", НоваяСтрока.Имя);
				
			Иначе
				
				одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ПриоритетОбъектовОбмена" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
			Если Значение = "Ниже" Тогда
				НоваяСтрока.ПриоритетОбъектовОбмена = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаНиже;
			ИначеЕсли Значение = "Совпадает" Тогда
				НоваяСтрока.ПриоритетОбъектовОбмена = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаСовпадает;
			КонецЕсли;
			
		// Настройки вариантов поиска.
		ИначеЕсли ИмяУзла = "НастройкаВариантовПоискаОбъектов" Тогда
		
			ЗагрузитьНастройкиВариантовПоиска(ПравилаОбмена, НоваяСтрока);
			
		ИначеЕсли ИмяУзла = "ПоискПоТабличнымЧастям" Тогда
			
			// Загружаем информацию по ключевым полям поиска в табличных частях.
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
			Для Номер = 1 По СтрЧислоСтрок(Значение) Цикл
				
				ТекущаяСтрока = СтрПолучитьСтроку(Значение, Номер);
				
				СтрокаПоиска = ОтделитьРазделителем(ТекущаяСтрока, ":");
				
				СтрокаТаблицы = НоваяСтрока.ПоискПоТабличнымЧастям.Добавить();
				
				СтрокаТаблицы.ИмяЭлемента               = ТекущаяСтрока;
				СтрокаТаблицы.КлючевыеПоляПоиска        = СтрокаПоиска;
				СтрокаТаблицы.МассивКлючевыхПолейПоиска = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(СтрокаПоиска);
				СтрокаТаблицы.Валидное                  = СтрокаТаблицы.МассивКлючевыхПолейПоиска.Количество() <> 0;
				
			КонецЦикла;
			
		ИначеЕсли ИмяУзла = "ПоляПоиска" Тогда
			
			НоваяСтрока.ПоляПоиска = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "ПоляТаблицы" Тогда
			
			НоваяСтрока.ПоляТаблицы = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "ОбъектСДвижениями" Тогда
			
			НоваяСтрока.ОбъектСДвижениями = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
			
		ИначеЕсли (ИмяУзла = "Правило") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
		
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Если РежимОбмена <> "Загрузка" Тогда
		
		// ПОЛУЧАЕМ СВОЙСТВА ПОИСКА ПОЛЕЙ ТЧ ДЛЯ ПРАВИЛ ЗАГРУЗКИ ДАННЫХ (ЗаписьXML)
		
		ИтоговаяСтрокаПоискаПоТЧ = "";
		
		// В приемник нужно передать информацию о полях поиска для табличных частей.
		Для Каждого СтрокаСвойств Из НоваяСтрока.Свойства Цикл
			
			Если Не СтрокаСвойств.ЭтоГруппа
				ИЛИ ПустаяСтрока(СтрокаСвойств.ВидПриемника)
				ИЛИ ПустаяСтрока(СтрокаСвойств.Приемник) Тогда
				
				Продолжить;
				
			КонецЕсли;
			
			Если ПустаяСтрока(СтрокаСвойств.СтрокаПолейПоиска) Тогда
				Продолжить;
			КонецЕсли;
			
			ИтоговаяСтрокаПоискаПоТЧ = ИтоговаяСтрокаПоискаПоТЧ + Символы.ПС + СтрокаСвойств.ВидПриемника + "." + СтрокаСвойств.Приемник + ":" + СтрокаСвойств.СтрокаПолейПоиска;
			
		КонецЦикла;
		
		ИтоговаяСтрокаПоискаПоТЧ = СокрЛП(ИтоговаяСтрокаПоискаПоТЧ);
		
		Если Не ПустаяСтрока(ИтоговаяСтрокаПоискаПоТЧ) Тогда
			
			одЗаписатьЭлемент(ЗаписьXML, "ПоискПоТабличнымЧастям", ИтоговаяСтрокаПоискаПоТЧ);
			
		КонецЕсли;
		
	КонецЕсли;
	
	ПоляТаблицы = "";
	ПоляПоиска = "";
	Если НоваяСтрока.Свойства.Количество() > 0
		Или НоваяСтрока.СвойстваПоиска.Количество() > 0 Тогда
		
		СвойстваМассив = НоваяСтрока.Свойства.Скопировать(Новый Структура("ЭтоГруппа, ИмяПараметраДляПередачи", Ложь, ""), "Приемник").ВыгрузитьКолонку("Приемник");
		
		СвойстваПоискаМассив               = НоваяСтрока.СвойстваПоиска.Скопировать(Новый Структура("ЭтоГруппа, ИмяПараметраДляПередачи", Ложь, ""), "Приемник").ВыгрузитьКолонку("Приемник");
		СвойстваПоискаМассивДополнительный = НоваяСтрока.Свойства.Скопировать(Новый Структура("ЭтоПолеПоиска, ИмяПараметраДляПередачи", Истина, ""), "Приемник").ВыгрузитьКолонку("Приемник");
		
		Для каждого Значение Из СвойстваПоискаМассивДополнительный Цикл
			
			СвойстваПоискаМассив.Добавить(Значение);
			
		КонецЦикла;
		
		// Удаляем из массива полей поиска значение {УникальныйИдентификатор}.
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(СвойстваПоискаМассив, "{УникальныйИдентификатор}");
		
		// Получаем значение переменной СвойстваМассив.
		ТаблицаПоляТаблицы = Новый ТаблицаЗначений;
		ТаблицаПоляТаблицы.Колонки.Добавить("Приемник");
		
		ОбщегоНазначенияКлиентСервер.ДополнитьТаблицуИзМассива(ТаблицаПоляТаблицы, СвойстваМассив, "Приемник");
		ОбщегоНазначенияКлиентСервер.ДополнитьТаблицуИзМассива(ТаблицаПоляТаблицы, СвойстваПоискаМассив, "Приемник");
		
		ТаблицаПоляТаблицы.Свернуть("Приемник");
		СвойстваМассив = ТаблицаПоляТаблицы.ВыгрузитьКолонку("Приемник");
		
		ПоляТаблицы = СтрСоединить(СвойстваМассив, ",");
		ПоляПоиска  = СтрСоединить(СвойстваПоискаМассив, ",");
		
	КонецЕсли;
	
	Если РежимОбмена = "Загрузка" Тогда
		
		// Загрузка правил корреспондента - необходимо запомнить поля поиска и поля таблицы.
		Если Не ЗначениеЗаполнено(НоваяСтрока.ПоляТаблицы) Тогда
			НоваяСтрока.ПоляТаблицы = ПоляТаблицы;
		КонецЕсли;
		
		Если Не ЗначениеЗаполнено(НоваяСтрока.ПоляПоиска) Тогда
			НоваяСтрока.ПоляПоиска = ПоляПоиска;
		КонецЕсли;
		
	Иначе
		
		Если Не ПустаяСтрока(ПоляТаблицы) Тогда
			одЗаписатьЭлемент(ЗаписьXML, "ПоляТаблицы", ПоляТаблицы);
		КонецЕсли;
		
		Если Не ПустаяСтрока(ПоляПоиска) Тогда
			одЗаписатьЭлемент(ЗаписьXML, "ПоляПоиска", ПоляПоиска);
		КонецЕсли;
		
	КонецЕсли;
	
	// закрываем узел
	ЗаписьXML.ЗаписатьКонецЭлемента(); // Правило
	
	// Быстрый доступ к ПКО по имени.
	Правила.Вставить(НоваяСтрока.Имя, НоваяСтрока);
	
КонецПроцедуры

Процедура ЗагрузитьНастройкуВариантовПоиска(ПравилаОбмена, НоваяСтрока)
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		ТипУзла = ПравилаОбмена.ТипУзла;
		
		Если ИмяУзла = "ИмяНастройкиДляАлгоритма" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Если РежимЗагрузкиИнформацииОПравилахОбмена Тогда
				НоваяСтрока.ИмяНастройкиДляАлгоритма = Значение;
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ИмяНастройкиДляПользователя" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Если РежимЗагрузкиИнформацииОПравилахОбмена Тогда
				НоваяСтрока.ИмяНастройкиДляПользователя = Значение;
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ОписаниеНастройкиДляПользователя" Тогда
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Если РежимЗагрузкиИнформацииОПравилахОбмена Тогда
				НоваяСтрока.ОписаниеНастройкиДляПользователя = Значение;
			КонецЕсли;
			
		ИначеЕсли (ИмяУзла = "ВариантПоиска") И (ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		Иначе
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры

// Возвращаемое значение:
//   ТаблицаЗначений:
//     * КодПравилаОбмена - Строка
//     * НаименованиеПравилаОбмена - Строка
//
Функция РезультатыЗагрузкиИнформацииОПоляхПоиска()
	Возврат ТаблицаРезультатовЗагрузкиИнформацииОПоляхПоиска;
КонецФункции

Процедура ЗагрузитьНастройкиВариантовПоиска(ПравилаОбмена, СтрокаБазовогоПКО)

	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		ТипУзла = ПравилаОбмена.ТипУзла;
		
		Если ИмяУзла = "ВариантПоиска" Тогда
			
			Если РежимЗагрузкиИнформацииОПравилахОбмена Тогда
				СтрокаНастройки = РезультатыЗагрузкиИнформацииОПоляхПоиска().Добавить();
				СтрокаНастройки.КодПравилаОбмена = СтрокаБазовогоПКО.Имя;
				СтрокаНастройки.НаименованиеПравилаОбмена = СтрокаБазовогоПКО.Наименование;
			Иначе
				СтрокаНастройки = Неопределено;
			КонецЕсли;
			
			ЗагрузитьНастройкуВариантовПоиска(ПравилаОбмена, СтрокаНастройки);
			
		ИначеЕсли (ИмяУзла = "НастройкаВариантовПоискаОбъектов") И (ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		Иначе
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Осуществляет загрузку правил конвертации объектов.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьПравилаКонвертации(ПравилаОбмена, ЗаписьXML)
	
	ТаблицаПравилКонвертации.Очистить();
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("ПравилаКонвертацииОбъектов");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Правило" Тогда
			
			ЗагрузитьПравилоКонвертации(ПравилаОбмена, ЗаписьXML);
			
		ИначеЕсли (ИмяУзла = "ПравилаКонвертацииОбъектов") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	ЗагрузитьПравилоКонвертации_РежимыВыгрузкиОбъектовОбмена(ЗаписьXML);
	
	ЗаписьXML.ЗаписатьКонецЭлемента();
	
	ТаблицаПравилКонвертации.Индексы.Добавить("Приемник");
	
КонецПроцедуры

// Осуществляет загрузку группы правил очистки данных в соответствии с форматом правил обмена.
//
// Параметры:
//  НоваяСтрока    - строка дерева значений, описывающая группу правил очистки данных.
// 
Процедура ЗагрузитьГруппуПОД(ПравилаОбмена, НоваяСтрока)

	НоваяСтрока.ЭтоГруппа = Истина;
	НоваяСтрока.Включить  = Число(Не одАтрибут(ПравилаОбмена, ТипБулево, "Отключить"));
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		ТипУзла = ПравилаОбмена.ТипУзла;
		
		Если      ИмяУзла = "Код" Тогда
			НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);

		ИначеЕсли ИмяУзла = "Наименование" Тогда
			НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
		
		ИначеЕсли ИмяУзла = "Порядок" Тогда
			НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, ТипЧисло);
			
		ИначеЕсли ИмяУзла = "Правило" Тогда
			СтрокаДЗ = НоваяСтрока.Строки.Добавить();
			ЗагрузитьПОД(ПравилаОбмена, СтрокаДЗ);
			
		ИначеЕсли (ИмяУзла = "Группа") И (ТипУзла = ТипУзлаXMLНачалоЭлемента) Тогда
			СтрокаДЗ = НоваяСтрока.Строки.Добавить();
			ЗагрузитьГруппуПОД(ПравилаОбмена, СтрокаДЗ);
			
		ИначеЕсли (ИмяУзла = "Группа") И (ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;

	
	Если ПустаяСтрока(НоваяСтрока.Наименование) Тогда
		НоваяСтрока.Наименование = НоваяСтрока.Имя;
	КонецЕсли; 
	
КонецПроцедуры

// Осуществляет загрузку правила очистки данных в соответствии с форматом правил обмена.
//
// Параметры:
//  НоваяСтрока    - строка дерева значений, описывающая правило очистки данных.
// 
Процедура ЗагрузитьПОД(ПравилаОбмена, НоваяСтрока)
	
	НоваяСтрока.Включить = Число(Не одАтрибут(ПравилаОбмена, ТипБулево, "Отключить"));
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Код" Тогда
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			НоваяСтрока.Имя = Значение;

		ИначеЕсли ИмяУзла = "Наименование" Тогда
			НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
		
		ИначеЕсли ИмяУзла = "Порядок" Тогда
			НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, ТипЧисло);
			
		ИначеЕсли ИмяУзла = "СпособОтбораДанных" Тогда
			НоваяСтрока.СпособОтбораДанных = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);

		ИначеЕсли ИмяУзла = "ОбъектВыборки" Тогда
			
			Если Не РежимЗагрузкиИнформацииОПравилахОбмена Тогда
			
				ОбъектВыборки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
				Если Не ПустаяСтрока(ОбъектВыборки) Тогда
					НоваяСтрока.ОбъектВыборки = Тип(ОбъектВыборки);
				КонецЕсли;
				
			КонецЕсли;

		ИначеЕсли ИмяУзла = "УдалятьЗаПериод" Тогда
			НоваяСтрока.УдалятьЗаПериод = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "Непосредственно" Тогда
			НоваяСтрока.Непосредственно = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);

		
		// Обработчики событий

		ИначеЕсли ИмяУзла = "ПередОбработкойПравила" Тогда
			НоваяСтрока.ПередОбработкой = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПОД_[ИмяПОД]_ПередОбработкойПравила";
			НоваяСтрока.ИмяОбработчикаПередОбработкой = СтрЗаменить(ИмяОбработчика, "[ИмяПОД]", НоваяСтрока.Имя);
			
		ИначеЕсли ИмяУзла = "ПослеОбработкиПравила" Тогда
			НоваяСтрока.ПослеОбработки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПОД_[ИмяПОД]_ПослеОбработкиПравила";
			НоваяСтрока.ИмяОбработчикаПослеОбработки = СтрЗаменить(ИмяОбработчика, "[ИмяПОД]", НоваяСтрока.Имя);
			
		ИначеЕсли ИмяУзла = "ПередУдалениемОбъекта" Тогда
			НоваяСтрока.ПередУдалением = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПОД_[ИмяПОД]_ПередУдалениемОбъекта";
			НоваяСтрока.ИмяОбработчикаПередУдалением = СтрЗаменить(ИмяОбработчика, "[ИмяПОД]", НоваяСтрока.Имя);
			
		// Выход
		ИначеЕсли (ИмяУзла = "Правило") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;

	
	Если ПустаяСтрока(НоваяСтрока.Наименование) Тогда
		НоваяСтрока.Наименование = НоваяСтрока.Имя;
	КонецЕсли; 
	
КонецПроцедуры

// Осуществляет загрузку правил очистки данных.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьПравилаОчистки(ПравилаОбмена, ЗаписьXML)

	КоллекцияПравилаОчисткиДанных().Строки.Очистить();
	СтрокиДЗ = КоллекцияПравилаОчисткиДанных().Строки;
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("ПравилаОчисткиДанных");

	Пока ПравилаОбмена.Прочитать() Цикл
		
		ТипУзла = ПравилаОбмена.ТипУзла;
		
		Если ТипУзла = ТипУзлаXMLНачалоЭлемента Тогда
			ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
			Если РежимОбмена <> "Загрузка" Тогда
				ЗаписьXML.ЗаписатьНачалоЭлемента(ПравилаОбмена.Имя);
				Пока ПравилаОбмена.ПрочитатьАтрибут() Цикл
					ЗаписьXML.ЗаписатьАтрибут(ПравилаОбмена.Имя, ПравилаОбмена.Значение);
				КонецЦикла;
			Иначе
				Если ИмяУзла = "Правило" Тогда
					СтрокаДЗ = СтрокиДЗ.Добавить();
					ЗагрузитьПОД(ПравилаОбмена, СтрокаДЗ);
				ИначеЕсли ИмяУзла = "Группа" Тогда
					СтрокаДЗ = СтрокиДЗ.Добавить();
					ЗагрузитьГруппуПОД(ПравилаОбмена, СтрокаДЗ);
				КонецЕсли;
			КонецЕсли;
		ИначеЕсли ТипУзла = ТипУзлаXMLКонецЭлемента Тогда
			ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
			Если ИмяУзла = "ПравилаОчисткиДанных" Тогда
				Прервать;
			Иначе
				Если РежимОбмена <> "Загрузка" Тогда
					ЗаписьXML.ЗаписатьКонецЭлемента();
				КонецЕсли;
			КонецЕсли;
		ИначеЕсли ТипУзла = ТипУзлаXMLТекст Тогда
			Если РежимОбмена <> "Загрузка" Тогда
				ЗаписьXML.ЗаписатьТекст(ПравилаОбмена.Значение);
			КонецЕсли;
		КонецЕсли; 
	КонецЦикла;

	СтрокиДЗ.Сортировать("Порядок", Истина);
	
	ЗаписьXML.ЗаписатьКонецЭлемента();
	
КонецПроцедуры

// Осуществляет загрузку алгоритма в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьАлгоритм(ПравилаОбмена, ЗаписьXML)

	ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, ТипБулево, "ИспользуетсяПриЗагрузке");
	Имя                     = одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Текст" Тогда
			Текст = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
		ИначеЕсли (ИмяУзла = "Алгоритм") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		Иначе
			одПропустить(ПравилаОбмена);
		КонецЕсли;
		
	КонецЦикла;

	
	Если ИспользуетсяПриЗагрузке Тогда
		Если РежимОбмена = "Загрузка" Тогда
			Алгоритмы.Вставить(Имя, Текст);
		Иначе
			ЗаписьXML.ЗаписатьНачалоЭлемента("Алгоритм");
			УстановитьАтрибут(ЗаписьXML, "ИспользуетсяПриЗагрузке", Истина);
			УстановитьАтрибут(ЗаписьXML, "Имя",   Имя);
			одЗаписатьЭлемент(ЗаписьXML, "Текст", Текст);
			ЗаписьXML.ЗаписатьКонецЭлемента();
		КонецЕсли;
	Иначе
		Если РежимОбмена <> "Загрузка" Тогда
			Алгоритмы.Вставить(Имя, Текст);
		КонецЕсли;
	КонецЕсли;
	
	
КонецПроцедуры

// Осуществляет загрузку алгоритмов в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьАлгоритмы(ПравилаОбмена, ЗаписьXML)

	Алгоритмы.Очистить();

	ЗаписьXML.ЗаписатьНачалоЭлемента("Алгоритмы");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		Если      ИмяУзла = "Алгоритм" Тогда
			ЗагрузитьАлгоритм(ПравилаОбмена, ЗаписьXML);
		ИначеЕсли (ИмяУзла = "Алгоритмы") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;

	ЗаписьXML.ЗаписатьКонецЭлемента();
	
КонецПроцедуры

// Осуществляет загрузку запроса в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьЗапрос(ПравилаОбмена, ЗаписьXML)

	ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, ТипБулево, "ИспользуетсяПриЗагрузке");
	Имя                     = одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Текст" Тогда
			Текст = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
		ИначеЕсли (ИмяУзла = "Запрос") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		Иначе
			одПропустить(ПравилаОбмена);
		КонецЕсли;
		
	КонецЦикла;

	Если ИспользуетсяПриЗагрузке Тогда
		Если РежимОбмена = "Загрузка" Тогда
			Запрос	= Новый Запрос(Текст);
			Запросы.Вставить(Имя, Запрос);
		Иначе
			ЗаписьXML.ЗаписатьНачалоЭлемента("Запрос");
			УстановитьАтрибут(ЗаписьXML, "ИспользуетсяПриЗагрузке", Истина);
			УстановитьАтрибут(ЗаписьXML, "Имя",   Имя);
			одЗаписатьЭлемент(ЗаписьXML, "Текст", Текст);
			ЗаписьXML.ЗаписатьКонецЭлемента();
		КонецЕсли;
	Иначе
		Если РежимОбмена <> "Загрузка" Тогда
			Запрос	= Новый Запрос(Текст);
			Запросы.Вставить(Имя, Запрос);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

// Осуществляет загрузку запросов в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьЗапросы(ПравилаОбмена, ЗаписьXML)

	Запросы.Очистить();

	ЗаписьXML.ЗаписатьНачалоЭлемента("Запросы");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Запрос" Тогда
			ЗагрузитьЗапрос(ПравилаОбмена, ЗаписьXML);
		ИначеЕсли (ИмяУзла = "Запросы") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;

	ЗаписьXML.ЗаписатьКонецЭлемента();
	
КонецПроцедуры

// Осуществляет загрузку параметров в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//
Процедура ЗагрузитьПараметры(ПравилаОбмена, ЗаписьXML)

	Параметры.Очистить();
	СобытияПослеЗагрузкиПараметров.Очистить();
	ТаблицаНастройкиПараметров.Очистить();
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("Параметры");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		ТипУзла = ПравилаОбмена.ТипУзла;

		Если ИмяУзла = "Параметр" И ТипУзла = ТипУзлаXMLНачалоЭлемента Тогда
			
			// Загрузка по версии правил 2.01.
			Имя                     = одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
			Наименование            = одАтрибут(ПравилаОбмена, ТипСтрока, "Наименование");
			УстанавливатьВДиалоге   = одАтрибут(ПравилаОбмена, ТипБулево, "УстанавливатьВДиалоге");
			СтрокаТипаЗначения      = одАтрибут(ПравилаОбмена, ТипСтрока, "ТипЗначения");
			ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, ТипБулево, "ИспользуетсяПриЗагрузке");
			ПередаватьПараметрПриВыгрузке = одАтрибут(ПравилаОбмена, ТипБулево, "ПередаватьПараметрПриВыгрузке");
			ПравилоКонвертации = одАтрибут(ПравилаОбмена, ТипСтрока, "ПравилоКонвертации");
			АлгоритмПослеЗагрузкиПараметра = одАтрибут(ПравилаОбмена, ТипСтрока, "ПослеЗагрузкиПараметра");
			
			Если Не ПустаяСтрока(АлгоритмПослеЗагрузкиПараметра) Тогда
				
				СобытияПослеЗагрузкиПараметров.Вставить(Имя, АлгоритмПослеЗагрузкиПараметра);
				
			КонецЕсли;
			
			// Определяем типы значений и устанавливаем начальные значения.
			Если Не ПустаяСтрока(СтрокаТипаЗначения) Тогда
				
				Попытка
					ТипЗначенияДанных = Тип(СтрокаТипаЗначения);
					ТипОпределен = ИСТИНА;
				Исключение
					ТипОпределен = ЛОЖЬ;
				КонецПопытки;
				
			Иначе
				
				ТипОпределен = ЛОЖЬ;
				
			КонецЕсли;
			
			Если ТипОпределен Тогда
				ЗначениеПараметра = одПолучитьПустоеЗначение(ТипЗначенияДанных);
				Параметры.Вставить(Имя, ЗначениеПараметра);
			Иначе
				ЗначениеПараметра = "";
				Параметры.Вставить(Имя);
			КонецЕсли;
						
			Если УстанавливатьВДиалоге = ИСТИНА Тогда
				
				СтрокаТаблицы              = ТаблицаНастройкиПараметров.Добавить();
				СтрокаТаблицы.Наименование = Наименование;
				СтрокаТаблицы.Имя          = Имя;
				СтрокаТаблицы.Значение = ЗначениеПараметра;				
				СтрокаТаблицы.ПередаватьПараметрПриВыгрузке = ПередаватьПараметрПриВыгрузке;
				СтрокаТаблицы.ПравилоКонвертации = ПравилоКонвертации;
				
			КонецЕсли;
			
			Если ИспользуетсяПриЗагрузке
				И РежимОбмена = "Выгрузка" Тогда
				
				ЗаписьXML.ЗаписатьНачалоЭлемента("Параметр");
				УстановитьАтрибут(ЗаписьXML, "Имя",   Имя);
				УстановитьАтрибут(ЗаписьXML, "Наименование", Наименование);
					
				Если НЕ ПустаяСтрока(АлгоритмПослеЗагрузкиПараметра) Тогда
					УстановитьАтрибут(ЗаписьXML, "ПослеЗагрузкиПараметра", XMLСтрока(АлгоритмПослеЗагрузкиПараметра));
				КонецЕсли;
				
				ЗаписьXML.ЗаписатьКонецЭлемента();
				
			КонецЕсли;

		ИначеЕсли (ТипУзла = ТипУзлаXMLТекст) Тогда
			
			// Для совместимости с версией правил 2.0 используем загрузку из строки.
			СтрокаПараметров = ПравилаОбмена.Значение;
			Для каждого Пар Из МассивИзСтроки(СтрокаПараметров) Цикл
				Параметры.Вставить(Пар);
			КонецЦикла;
			
		ИначеЕсли (ИмяУзла = "Параметры") И (ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;

	ЗаписьXML.ЗаписатьКонецЭлемента();

КонецПроцедуры

// Осуществляет загрузку обработки в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьОбработку(ПравилаОбмена, ЗаписьXML)

	Имя                     = одАтрибут(ПравилаОбмена, ТипСтрока, "Имя");
	Наименование            = одАтрибут(ПравилаОбмена, ТипСтрока, "Наименование");
	ЭтоОбработкаНастройки   = одАтрибут(ПравилаОбмена, ТипБулево, "ЭтоОбработкаНастройки");
	
	ИспользуетсяПриВыгрузке = одАтрибут(ПравилаОбмена, ТипБулево, "ИспользуетсяПриВыгрузке");
	ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, ТипБулево, "ИспользуетсяПриЗагрузке");

	СтрокаПараметров        = одАтрибут(ПравилаОбмена, ТипСтрока, "Параметры");
	
	ХранилищеОбработки      = одЗначениеЭлемента(ПравилаОбмена, ТипХранилищеЗначения);

	ПараметрыДопОбработок.Вставить(Имя, МассивИзСтроки(СтрокаПараметров));
	
	
	Если ИспользуетсяПриЗагрузке Тогда
		Если РежимОбмена <> "Загрузка" Тогда
			ЗаписьXML.ЗаписатьНачалоЭлемента("Обработка");
			УстановитьАтрибут(ЗаписьXML, "ИспользуетсяПриЗагрузке", Истина);
			УстановитьАтрибут(ЗаписьXML, "Имя",                     Имя);
			УстановитьАтрибут(ЗаписьXML, "Наименование",            Наименование);
			УстановитьАтрибут(ЗаписьXML, "ЭтоОбработкаНастройки",   ЭтоОбработкаНастройки);
			ЗаписьXML.ЗаписатьТекст(XMLСтрока(ХранилищеОбработки));
			ЗаписьXML.ЗаписатьКонецЭлемента();
		КонецЕсли;
	КонецЕсли;

	Если ЭтоОбработкаНастройки Тогда
		Если (РежимОбмена = "Загрузка") И ИспользуетсяПриЗагрузке Тогда
			ОбработкиНастройкиЗагрузки.Добавить(Имя, Наименование, , );
			
		ИначеЕсли (РежимОбмена = "Выгрузка") И ИспользуетсяПриВыгрузке Тогда
			ОбработкиНастройкиВыгрузки.Добавить(Имя, Наименование, , );
			
		КонецЕсли; 
	КонецЕсли; 
	
КонецПроцедуры

// Осуществляет загрузку внешних обработок в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//  ЗаписьXML      - ЗаписьXML - объект типа ЗаписьXML - правила, сохраняемые в файл обмена и
//                   используемые при загрузке данных.
//
Процедура ЗагрузитьОбработки(ПравилаОбмена, ЗаписьXML)

	ДопОбработки.Очистить();
	ПараметрыДопОбработок.Очистить();
	
	ОбработкиНастройкиВыгрузки.Очистить();
	ОбработкиНастройкиЗагрузки.Очистить();

	ЗаписьXML.ЗаписатьНачалоЭлемента("Обработки");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если      ИмяУзла = "Обработка" Тогда
			ЗагрузитьОбработку(ПравилаОбмена, ЗаписьXML);
		ИначеЕсли (ИмяУзла = "Обработки") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;

	ЗаписьXML.ЗаписатьКонецЭлемента();
	
КонецПроцедуры

// Осуществляет загрузку правила выгрузки данных в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена - ЧтениеXML - объект типа ЧтениеXML.
//
Процедура ЗагрузитьПВД(ПравилаОбмена)
	
	НоваяСтрока = КоллекцияПравилаВыгрузкиДанных().Добавить();
	
	НоваяСтрока.Включить = Не одАтрибут(ПравилаОбмена, ТипБулево, "Отключить");
		
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		Если ИмяУзла = "Код" Тогда
			
			НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "Наименование" Тогда
			
			НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
		
		ИначеЕсли ИмяУзла = "Порядок" Тогда
			
			НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, ТипЧисло);
			
		ИначеЕсли ИмяУзла = "СпособОтбораДанных" Тогда
			
			НоваяСтрока.СпособОтбораДанных = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "ВыбиратьДанныеДляВыгрузкиОднимЗапросом" Тогда
			
			// Параметр игнорируется при on-line обмене данными.
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "НеВыгружатьОбъектыСозданныеВБазеПриемнике" Тогда
			
			НоваяСтрока.НеВыгружатьОбъектыСозданныеВБазеПриемнике = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);

		ИначеЕсли ИмяУзла = "ИмяТипаПриемника" Тогда
			
			НоваяСтрока.ИмяТипаПриемника = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);

		ИначеЕсли ИмяУзла = "ОбъектВыборки" Тогда
			
			ОбъектВыборки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			
			Если Не РежимЗагрузкиИнформацииОПравилахОбмена Тогда
				
				НоваяСтрока.СинхронизироватьПоИдентификатору = СинхронизироватьПоИдентификаторуПВД(НоваяСтрока.ПравилоКонвертации);
				
				Если Не ПустаяСтрока(ОбъектВыборки) Тогда
					
					НоваяСтрока.ОбъектВыборки        = Тип(ОбъектВыборки);
					
				КонецЕсли;
				
				// Для поддержки отбора с помощью построителя.
				Если СтрНайти(ОбъектВыборки, "Ссылка.") Тогда
					НоваяСтрока.ИмяОбъектаДляЗапроса = СтрЗаменить(ОбъектВыборки, "Ссылка.", ".");
				Иначе
					НоваяСтрока.ИмяОбъектаДляЗапросаРегистра = СтрЗаменить(ОбъектВыборки, "Запись.", ".");
				КонецЕсли;
				
			КонецЕсли;

		ИначеЕсли ИмяУзла = "КодПравилаКонвертации" Тогда
			
			НоваяСтрока.ПравилоКонвертации = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);

		// Обработчики событий

		ИначеЕсли ИмяУзла = "ПередОбработкойПравила" Тогда
			НоваяСтрока.ПередОбработкой = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПВД_[ИмяПВД]_ПередОбработкойПравила";
			НоваяСтрока.ИмяОбработчикаПередОбработкой = СтрЗаменить(ИмяОбработчика, "[ИмяПВД]", НоваяСтрока.Имя);
			
		ИначеЕсли ИмяУзла = "ПослеОбработкиПравила" Тогда
			НоваяСтрока.ПослеОбработки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПВД_[ИмяПВД]_ПослеОбработкиПравила";
			НоваяСтрока.ИмяОбработчикаПослеОбработки = СтрЗаменить(ИмяОбработчика, "[ИмяПВД]", НоваяСтрока.Имя);
		
		ИначеЕсли ИмяУзла = "ПередВыгрузкойОбъекта" Тогда
			НоваяСтрока.ПередВыгрузкой = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПВД_[ИмяПВД]_ПередВыгрузкойОбъекта";
			НоваяСтрока.ИмяОбработчикаПередВыгрузкой = СтрЗаменить(ИмяОбработчика, "[ИмяПВД]", НоваяСтрока.Имя);
			
		ИначеЕсли ИмяУзла = "ПослеВыгрузкиОбъекта" Тогда
			НоваяСтрока.ПослеВыгрузки = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			ИмяОбработчика = "ПВД_[ИмяПВД]_ПослеВыгрузкиОбъекта";
			НоваяСтрока.ИмяОбработчикаПослеВыгрузки = СтрЗаменить(ИмяОбработчика, "[ИмяПВД]", НоваяСтрока.Имя);
			
		ИначеЕсли (ИмяУзла = "Правило") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;

	Если ПустаяСтрока(НоваяСтрока.Наименование) Тогда
		НоваяСтрока.Наименование = НоваяСтрока.Имя;
	КонецЕсли;
	
КонецПроцедуры

// Осуществляет загрузку правил выгрузки данных в соответствии с форматом правил обмена.
//
// Параметры:
//  ПравилаОбмена  - ЧтениеXML - объект типа ЧтениеXML.
//
Процедура ЗагрузитьПравилаВыгрузки(ПравилаОбмена)
	
	ТаблицаПравилВыгрузки.Очистить();
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Правило" Тогда
			
			ЗагрузитьПВД(ПравилаОбмена);
			
		ИначеЕсли (ИмяУзла = "ПравилаВыгрузкиДанных") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;

КонецПроцедуры

Функция СинхронизироватьПоИдентификаторуПВД(Знач ИмяПКО)
	
	ПКО = НайтиПравило(Неопределено, ИмяПКО);
	
	Если ПКО <> Неопределено Тогда
		
		Возврат (ПКО.СинхронизироватьПоИдентификатору = Истина);
		
	КонецЕсли;
	
	Возврат Ложь;
КонецФункции

Процедура ЗагрузитьПравилоКонвертации_РежимыВыгрузкиОбъектовОбмена(ЗаписьXML)
	
	ТипИсточника = "ПеречислениеСсылка.РежимыВыгрузкиОбъектовОбмена";
	ТипПриемника = "ПеречислениеСсылка.РежимыВыгрузкиОбъектовОбмена";
	
	Отбор = Новый Структура;
	Отбор.Вставить("ТипИсточника", ТипИсточника);
	Отбор.Вставить("ТипПриемника", ТипПриемника);
	
	Если КоллекцияПравилаКонвертации().НайтиСтроки(Отбор).Количество() <> 0 Тогда
		Возврат;
	КонецЕсли;
	
	НоваяСтрока = КоллекцияПравилаКонвертации().Добавить();
	
	НоваяСтрока.ЗапоминатьВыгруженные = Истина;
	НоваяСтрока.НеЗамещать            = Ложь;
	НоваяСтрока.ПриоритетОбъектовОбмена = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаВыше;
	
	НоваяСтрока.Свойства            = ТаблицаПравилКонвертацииСвойств.Скопировать();
	НоваяСтрока.СвойстваПоиска      = ТаблицаПравилКонвертацииСвойств.Скопировать();
	НоваяСтрока.СвойстваОтключенные = ТаблицаПравилКонвертацииСвойств.Скопировать();
	
	НоваяСтрока.Имя = "РежимыВыгрузкиОбъектовОбмена";
	НоваяСтрока.Источник = Тип(ТипИсточника);
	НоваяСтрока.Приемник = ТипПриемника;
	НоваяСтрока.ТипИсточника = ТипИсточника;
	НоваяСтрока.ТипПриемника = ТипПриемника;
	
	Значения = Новый Структура;
	Значения.Вставить("ВыгружатьВсегда",           "ВыгружатьВсегда");
	Значения.Вставить("ВыгружатьПоУсловию",        "ВыгружатьПоУсловию");
	Значения.Вставить("ВыгружатьПриНеобходимости", "ВыгружатьПриНеобходимости");
	Значения.Вставить("ВыгружатьВручную",          "ВыгружатьВручную");
	Значения.Вставить("НеВыгружать",               "НеВыгружать");
	НоваяСтрока.ЗначенияПредопределенныхДанныхПрочитанные = Значения;
	
	ПоискПоТабличнымЧастям = Новый ТаблицаЗначений;
	ПоискПоТабличнымЧастям.Колонки.Добавить("ИмяЭлемента");
	ПоискПоТабличнымЧастям.Колонки.Добавить("МассивКлючевыхПолейПоиска");
	ПоискПоТабличнымЧастям.Колонки.Добавить("КлючевыеПоляПоиска");
	ПоискПоТабличнымЧастям.Колонки.Добавить("Валидное", одОписаниеТипа("Булево"));
	НоваяСтрока.ПоискПоТабличнымЧастям = ПоискПоТабличнымЧастям;
	
	Менеджеры[НоваяСтрока.Источник].ПКО = НоваяСтрока;
	
	Правила.Вставить(НоваяСтрока.Имя, НоваяСтрока);
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("Правило");
	одЗаписатьЭлемент(ЗаписьXML, "Код", НоваяСтрока.Имя);
	одЗаписатьЭлемент(ЗаписьXML, "Источник", НоваяСтрока.ТипИсточника);
	одЗаписатьЭлемент(ЗаписьXML, "Приемник", НоваяСтрока.ТипПриемника);
	ЗаписьXML.ЗаписатьКонецЭлемента(); // Правило
	
КонецПроцедуры

#КонецОбласти

#Область ПроцедурыРаботыСПравиламиОбмена

// Осуществляет поиск правила конвертации по имени или в соответствии с типом
// переданного объекта.
//
// Параметры:
//   Объект     - Произвольный - объект-источник, для которого ищем правило конвертации.
//   ИмяПравила - Строка - имя правила конвертации.
//
// Возвращаемое значение:
//   СтрокаТаблицыЗначений - ссылка на правило конвертации (строка в таблице правил):
//     * Имя - Строка
//     * Наименование - Строка
//     * Источник - Строка
//     * Свойства - см. КоллекцияПравилаКонвертацииСвойств
// 
Функция НайтиПравило(Объект = Неопределено, ИмяПравила = "")

	Если Не ПустаяСтрока(ИмяПравила) Тогда
		
		Правило = Правила[ИмяПравила]; // см. НайтиПравило
		
	Иначе
		
		Правило = Менеджеры[ТипЗнч(Объект)];
		Если Правило <> Неопределено Тогда
			Правило = Правило.ПКО; // см. НайтиПравило
			
			Если Правило <> Неопределено Тогда
				ИмяПравила = Правило.Имя;
			КонецЕсли;
			
		КонецЕсли; 
		
	КонецЕсли;
	
	Возврат Правило;
	
КонецФункции

// Возвращаемое значение:
//   Структура:
//     * ВерсияФорматаХраненияПравил - Число
//     * Конвертация
//     * ТаблицаПравилВыгрузки -  см. КоллекцияПравилаВыгрузкиДанных
//     * ТаблицаПравилКонвертации - см. КоллекцияПравилаКонвертации
//     * ТаблицаНастройкиПараметров
//     * Алгоритмы
//     * Запросы
//     * Параметры
//     * XMLПравила
//     * СтрокаТиповДляПриемника
//
Функция СтруктураПравилКонвертации()
	
	Если СохраненныеНастройки = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Возврат СохраненныеНастройки.Получить();
	
КонецФункции

Процедура ВосстановитьПравилаИзВнутреннегоФормата() Экспорт
	
	СтруктураПравил = СтруктураПравилКонвертации();

	Если СтруктураПравил = Неопределено Тогда
		Возврат;
	КонецЕсли;	
	
	// Выполняем проверку на версию формата хранения правил обмена.
	ВерсияФорматаХраненияПравил = Неопределено;
	СтруктураПравил.Свойство("ВерсияФорматаХраненияПравил", ВерсияФорматаХраненияПравил);
	Если ВерсияФорматаХраненияПравил <> ВерсияФорматаХраненияПравилОбмена() Тогда
		ВызватьИсключение НСтр("ru = 'Версия формата хранения правил обмена не соответствует ожидаемой.
			|Требуется выполнить загрузку правил обмена повторно.'");
	КонецЕсли;
	
	Конвертация                = СтруктураПравил.Конвертация;
	ТаблицаПравилВыгрузки      = СтруктураПравил.ТаблицаПравилВыгрузки;
	ТаблицаПравилКонвертации   = СтруктураПравил.ТаблицаПравилКонвертации;
	ТаблицаНастройкиПараметров = СтруктураПравил.ТаблицаНастройкиПараметров;
	
	Алгоритмы                  = СтруктураПравил.Алгоритмы;
	ЗапросыДляВосстановления   = СтруктураПравил.Запросы;
	Параметры                  = СтруктураПравил.Параметры;
	
	XMLПравила                = СтруктураПравил.XMLПравила;
	СтрокаТиповДляПриемника   = СтруктураПравил.СтрокаТиповДляПриемника;
	
	ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта    = Не ПустаяСтрока(Конвертация.ПередВыгрузкойОбъекта);
	ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта     = Не ПустаяСтрока(Конвертация.ПослеВыгрузкиОбъекта);
	ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта    = Не ПустаяСтрока(Конвертация.ПередЗагрузкойОбъекта);
	ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта     = Не ПустаяСтрока(Конвертация.ПослеЗагрузкиОбъекта);
	ЕстьГлобальныйОбработчикПередКонвертациейОбъекта = Не ПустаяСтрока(Конвертация.ПередКонвертациейОбъекта);

	// Восстанавливаем запросы
	Запросы.Очистить();
	Для Каждого ЭлементСтруктуры Из ЗапросыДляВосстановления Цикл
		Запрос = Новый Запрос(ЭлементСтруктуры.Значение);
		Запросы.Вставить(ЭлементСтруктуры.Ключ, Запрос);
	КонецЦикла;
	
	ИнициализироватьМенеджерыИСообщения();
	
	Правила.Очистить();
	
	Для Каждого СтрокаТаблицы Из КоллекцияПравилаКонвертации() Цикл
		
		Если РежимОбмена = "Выгрузка" Тогда
			
			ПолучитьЗначенияПредопределенныхДанных(СтрокаТаблицы);
			
		КонецЕсли;
		
		Правила.Вставить(СтрокаТаблицы.Имя, СтрокаТаблицы);
		
		Если РежимОбмена = "Выгрузка" И СтрокаТаблицы.Источник <> Неопределено Тогда
			
			Попытка
				Если ТипЗнч(СтрокаТаблицы.Источник) = ТипСтрока Тогда
					Менеджеры[Тип(СтрокаТаблицы.Источник)].ПКО = СтрокаТаблицы;
				Иначе
					Менеджеры[СтрокаТаблицы.Источник].ПКО = СтрокаТаблицы;
				КонецЕсли;
			Исключение
				ЗаписатьИнформациюОбОшибкеВПротокол(11, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
					Строка(СтрокаТаблицы.Источник));
			КонецПопытки;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура УстановитьЗначениеПараметраВТаблице(ИмяПараметра, ЗначениеПараметра)
	
	СтрокаТаблицы = ТаблицаНастройкиПараметров.Найти(ИмяПараметра, "Имя");
	
	Если СтрокаТаблицы <> Неопределено Тогда
		
		СтрокаТаблицы.Значение = ЗначениеПараметра;	
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ИнициализироватьПервоначальныеЗначенияПараметров()
	
	Для Каждого ТекПараметр Из Параметры Цикл
		
		УстановитьЗначениеПараметраВТаблице(ТекПараметр.Ключ, ТекПараметр.Значение);
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработкаПравилОчистки

Процедура УдалитьОбъект(Объект, УдалитьНепосредственно, ИмяТипа = "")
	
	МетаданныеОбъекта = Объект.Метаданные();
	
	Если ОбщегоНазначения.ЭтоСправочник(МетаданныеОбъекта)
		Или ОбщегоНазначения.ЭтоПланВидовХарактеристик(МетаданныеОбъекта)
		Или ОбщегоНазначения.ЭтоПланСчетов(МетаданныеОбъекта)
		Или ОбщегоНазначения.ЭтоПланВидовРасчета(МетаданныеОбъекта) Тогда
		
		Предопределенный = Объект.Предопределенный;
	Иначе
		Предопределенный = Ложь;
	КонецЕсли;
	
	Если Предопределенный Тогда
		
		Возврат;
		
	КонецЕсли;
	
	Если УдалитьНепосредственно Тогда
		
		Объект.Удалить();
		
	Иначе
		
		УстановитьПометкуУдаленияУОбъекта(Объект, Истина, ИмяТипа);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ВыполнитьУдалениеОбъекта(Объект, Свойства, УдалитьНепосредственно)
	
	Если Свойства.ИмяТипа = "РегистрСведений" Тогда
		
		Объект.Удалить();
		
	Иначе
		
		УдалитьОбъект(Объект, УдалитьНепосредственно, Свойства.ИмяТипа);
		
	КонецЕсли;
	
КонецПроцедуры

// Производит удаление (или помечает на удаление) объект выборки в соответствии с указанным правилом.
//
// Параметры:
//  Объект         - Произвольный - удаляемый (помечаемый на удаление) объект выборки.
//  Правило        - СтрокаТаблицыЗначений - ссылка на правило очистки данных:
//    * Имя - Строка - имя правила.
//  Свойства       - Структура - свойства объекта метаданного удаляемого объекта.
//  ВходящиеДанные - Произвольный - произвольные вспомогательные данные.
// 
Процедура УдалениеОбъектаВыборки(Объект, Правило, Свойства, ВходящиеДанные)
	
	Отказ = Ложь;
	УдалитьНепосредственно = Правило.Непосредственно;
	
	// Обработчик ПередУдалениемОбъектаВыборки
	
	Если Не ПустаяСтрока(Правило.ПередУдалением) Тогда
	
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_ПОД_ПередУдалениемОбъекта(Правило, Объект, Отказ, УдалитьНепосредственно, ВходящиеДанные);
				
			Иначе
				
				Выполнить(Правило.ПередУдалением);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(29, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, Объект, "ПередУдалениемОбъектаВыборки");
			
		КонецПопытки;
		
		Если Отказ Тогда
		
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;

	Попытка
		
		ВыполнитьУдалениеОбъекта(Объект, Свойства, УдалитьНепосредственно);
		
	Исключение
		
		ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(24, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
			Правило.Имя, Объект, "");
		
	КонецПопытки;
	
КонецПроцедуры

// Очищает данные по указанному правилу.
//
// Параметры:
//  Правило - СтрокаТаблицыЗначений - ссылка на правило очистки данных:
//    * Имя - Строка - имя правила.
// 
Процедура ОчиститьДанныеПоПравилу(Правило)
	
	// Обработчик ПередОбработкой
	
	Отказ			= Ложь;
	ВыборкаДанных	= Неопределено;
	ИсходящиеДанные = Неопределено;
	
	// Обработчик ПередОбработкойПравилаОчистки
	Если Не ПустаяСтрока(Правило.ПередОбработкой) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_ПОД_ПередОбработкойПравила(Правило, Отказ, ИсходящиеДанные, ВыборкаДанных);
				
			Иначе
				
				Выполнить(Правило.ПередОбработкой);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(27, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, "", "ПередОбработкойПравилаОчистки");
						
		КонецПопытки;
			
		Если Отказ Тогда
			
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;
	
	// Стандартная выборка
	
	Свойства = Менеджеры[Правило.ОбъектВыборки];
	
	Если Правило.СпособОтбораДанных = "СтандартнаяВыборка" Тогда
		
		ИмяТипа		= Свойства.ИмяТипа;
		
		Если ИмяТипа = "РегистрБухгалтерии" 
			ИЛИ ИмяТипа = "Константы" Тогда
			
			Возврат;
			
		КонецЕсли;
		
		НужныВсеПоля  = Не ПустаяСтрока(Правило.ПередУдалением);
		
		Выборка = ВыборкаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, Истина, Правило.Непосредственно, НужныВсеПоля);
		
		Пока Выборка.Следующий() Цикл
			
			Если ИмяТипа =  "РегистрСведений" Тогда
				
				МенеджерЗаписи = Свойства.Менеджер.СоздатьМенеджерЗаписи(); 
				ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка);
									
				УдалениеОбъектаВыборки(МенеджерЗаписи, Правило, Свойства, ИсходящиеДанные);
									
			Иначе
					
				УдалениеОбъектаВыборки(Выборка.Ссылка.ПолучитьОбъект(), Правило, Свойства, ИсходящиеДанные);
					
			КонецЕсли;
				
		КонецЦикла;		

	ИначеЕсли Правило.СпособОтбораДанных = "ПроизвольныйАлгоритм" Тогда

		Если ВыборкаДанных <> Неопределено Тогда
			
			Выборка = ВыборкаДляВыгрузкиПоПроизвольномуАлгоритму(ВыборкаДанных);
			
			Если Выборка <> Неопределено Тогда
				
				Пока Выборка.Следующий() Цикл
					
					Если ИмяТипа =  "РегистрСведений" Тогда
				
						МенеджерЗаписи = Свойства.Менеджер.СоздатьМенеджерЗаписи(); 
						ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка);
											
						УдалениеОбъектаВыборки(МенеджерЗаписи, Правило, Свойства, ИсходящиеДанные);
											
					Иначе
							
						УдалениеОбъектаВыборки(Выборка.Ссылка.ПолучитьОбъект(), Правило, Свойства, ИсходящиеДанные);
							
					КонецЕсли;					
					
				КонецЦикла;	
				
			Иначе
				
				Для каждого Объект Из ВыборкаДанных Цикл
					
					УдалениеОбъектаВыборки(Объект.ПолучитьОбъект(), Правило, Свойства, ИсходящиеДанные);
					
				КонецЦикла;
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
	// Обработчик ПослеОбработкиПравилаОчистки
	
	Если Не ПустаяСтрока(Правило.ПослеОбработки) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_ПОД_ПослеОбработкиПравила(Правило);
				
			Иначе
				
				Выполнить(Правило.ПослеОбработки);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(28, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, "", "ПослеОбработкиПравилаОчистки");
			
		КонецПопытки;
		
	КонецЕсли;
	
КонецПроцедуры

// Обходит дерево правил очистки данных и выполняет очистку.
//
// Параметры:
//  Строки - СтрокаДереваЗначений - коллекция строк дерева правил очистки данных.
// 
Процедура ОбработатьПравилаОчистки(Строки)
	
	Для каждого ПравилоОчистки Из Строки Цикл
		
		Если ПравилоОчистки.Включить = 0 Тогда
			
			Продолжить;
			
		КонецЕсли; 

		Если ПравилоОчистки.ЭтоГруппа Тогда
			
			ОбработатьПравилаОчистки(ПравилоОчистки.Строки);
			Продолжить;
			
		КонецЕсли;
		
		ОчиститьДанныеПоПравилу(ПравилоОчистки);
		
	КонецЦикла; 
	
КонецПроцедуры

#КонецОбласти

#Область ПроцедурыЗагрузкиДанных

Процедура НачатьЧтениеСообщения(ЧтениеСообщения, АнализДанных = Ложь)
	
	Если ПустаяСтрока(ИмяФайлаОбмена) Тогда
		ВызватьИсключение ЗаписатьВПротоколВыполнения(15);
	КонецЕсли;
	
	ФайлОбмена = Новый ЧтениеXML;
	
	ФайлОбмена.ОткрытьФайл(ИмяФайлаОбмена);
	
	ФайлОбмена.Прочитать(); // ФайлОбмена
	
	Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	Если ФайлОбмена.ЛокальноеИмя <> "ФайлОбмена" Тогда
		// Возможно, это сообщение обмена в новом формате.
		Если ОбменДаннымиXDTOСервер.ПроверитьФорматСообщенияОбмена(ФайлОбмена) Тогда
			ВыполнитьПереходНаНовыйОбмен();
		Иначе
			ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
		КонецЕсли;
	КонецЕсли;
	
	ПолеВерсияФорматаВходящегоСообщенияОбмена = одАтрибут(ФайлОбмена, ТипСтрока, "ВерсияФормата");
	
	ВерсияКонфигурацииИсточника = "";
	Конвертация.Свойство("ВерсияКонфигурацииИсточника", ВерсияКонфигурацииИсточника);
	ВерсияИсточникаИзПравил = одАтрибут(ФайлОбмена, ТипСтрока, "ВерсияКонфигурацииИсточника");
	ТекстСообщения = "";
	
	Если ОбменДаннымиСервер.РазличаютсяВерсииКорреспондента(ИмяПланаОбмена(), КлючСообщенияЖурналаРегистрации(),
		ВерсияКонфигурацииИсточника, ВерсияИсточникаИзПравил, ТекстСообщения) Тогда
		
		ВызватьИсключение ТекстСообщения;
		
	КонецЕсли;
	
	ФайлОбмена.Прочитать(); // ПравилаОбмена
	
	Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	Если ФайлОбмена.ЛокальноеИмя <> "ПравилаОбмена" Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	Если ТаблицаПравилКонвертации.Количество() = 0 Тогда
		ЗагрузитьПравилаОбмена(ФайлОбмена, "ЧтениеXML");
		Если ФлагОшибки() Тогда
			ВызватьИсключение НСтр("ru = 'При загрузке правил обмена данными возникли ошибки.'");
		КонецЕсли;
	Иначе
		одПропустить(ФайлОбмена);
	КонецЕсли;
	
	// {Обработчик: ПередЗагрузкойДанных} Начало
	Если Не ПустаяСтрока(Конвертация.ПередЗагрузкойДанных) Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПередЗагрузкойДанных(ФайлОбмена, Отказ);
				
			Иначе
				
				Выполнить(Конвертация.ПередЗагрузкойДанных);
				
			КонецЕсли;
			
		Исключение
			ВызватьИсключение ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(22, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				НСтр("ru = 'ПередЗагрузкойДанных (конвертация)'"));
		КонецПопытки;
		
		Если Отказ Тогда
			ВызватьИсключение НСтр("ru = 'Отказ от загрузки сообщения обмена в обработчике ПередЗагрузкойДанных (конвертация).'");
		КонецЕсли;
		
	КонецЕсли;
	// {Обработчик: ПередЗагрузкойДанных} Окончание
	
	ФайлОбмена.Прочитать();
	
	Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	// НастройкаПользовательскогоПоиска (необязательный)
	Если ФайлОбмена.ЛокальноеИмя = "НастройкаПользовательскогоПоиска" Тогда
		ЗагрузитьИнформациюОПользовательскихПоляхПоиска();
		ФайлОбмена.Прочитать();
	КонецЕсли;
	
	// ИнформацияОТипахДанных (необязательный)
	Если ФайлОбмена.ЛокальноеИмя = "ИнформацияОТипахДанных" Тогда
		
		Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
			ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
		КонецЕсли;
		
		Если СоответствиеТиповДанныхДляЗагрузки().Количество() > 0 Тогда
			одПропустить(ФайлОбмена);
		Иначе
			ЗагрузитьИнформациюОТипахДанных();
			Если ФлагОшибки() Тогда
				ВызватьИсключение НСтр("ru = 'При загрузке информации о типах данных возникли ошибки.'");
			КонецЕсли;
		КонецЕсли;
		ФайлОбмена.Прочитать();
	КонецЕсли;
	
	// ЗначениеПараметра (необязательный) (несколько).
	Если ФайлОбмена.ЛокальноеИмя = "ЗначениеПараметра" Тогда
		
		Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
			ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
		КонецЕсли;
		
		ЗагрузитьЗначенияПараметровОбменаДанными();
		
		Пока ФайлОбмена.Прочитать() Цикл
			
			Если ФайлОбмена.ЛокальноеИмя = "ЗначениеПараметра" Тогда
				
				Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
					ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
				КонецЕсли;
				
				ЗагрузитьЗначенияПараметровОбменаДанными();
			Иначе
				Прервать;
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЕсли;
	
	// АлгоритмПослеЗагрузкиПараметров (необязательный)
	Если ФайлОбмена.ЛокальноеИмя = "АлгоритмПослеЗагрузкиПараметров" Тогда
		
		Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
			ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
		КонецЕсли;
		
		ВыполнитьАлгоритмПослеЗагрузкиПараметров(одЗначениеЭлемента(ФайлОбмена, ТипСтрока));
		ФайлОбмена.Прочитать();
	КонецЕсли;
	
	// ДанныеПоОбмену (обязательный)
	Если ФайлОбмена.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	Если ФайлОбмена.ЛокальноеИмя <> "ДанныеПоОбмену" Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	ПрочитатьДанныеПоОбмену(ЧтениеСообщения, АнализДанных);
	ФайлОбмена.Прочитать();
	
	Если ТранзакцияАктивна() Тогда
		ВызватьИсключение НСтр("ru = 'Блокировка получения данных не может быть установлена в активной транзакции.'");
	КонецЕсли;
	
	// Устанавливаем блокировку на узел отправителя.
	Попытка
		ЗаблокироватьДанныеДляРедактирования(ЧтениеСообщения.Отправитель);
	Исключение
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Ошибка установки блокировки на обмен данными.
			|Возможно, обмен данными выполняется другим сеансом.
			|
			|Подробности:
			|%1'"),
			ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
	КонецПопытки;
	
КонецПроцедуры

Процедура ВыполнитьОбработчикПослеЗагрузкиДанных()
	
	// {Обработчик: ПослеЗагрузкиДанных} Начало
	Если Не ПустаяСтрока(Конвертация.ПослеЗагрузкиДанных) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиДанных();
				
			Иначе
				
				Выполнить(Конвертация.ПослеЗагрузкиДанных);
				
			КонецЕсли;
			
		Исключение
			ВызватьИсключение ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(23, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				НСтр("ru = 'ПослеЗагрузкиДанных (конвертация)'"));
		КонецПопытки;
		
	КонецЕсли;
	// {Обработчик: ПослеЗагрузкиДанных} Окончание
	
КонецПроцедуры

Процедура ЗакончитьЧтениеСообщения(Знач ЧтениеСообщения)
	
	Если ФайлОбмена.ТипУзла <> ТипУзлаXML.КонецЭлемента Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	Если ФайлОбмена.ЛокальноеИмя <> "ФайлОбмена" Тогда
		ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
	КонецЕсли;
	
	ФайлОбмена.Прочитать(); // ФайлОбмена
	ФайлОбмена.Закрыть();
	
	НачатьТранзакцию();
	Попытка
		Если Не ЧтениеСообщения.АнализДанных Тогда
			ЧтениеСообщения.ОтправительОбъект.НомерПринятого = ЧтениеСообщения.НомерСообщения;
			ЧтениеСообщения.ОтправительОбъект.ОбменДанными.Загрузка = Истина;
			ЧтениеСообщения.ОтправительОбъект.Записать();
		КонецЕсли;
		
		Если ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Истина Тогда
			РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ЗафиксироватьВыполнениеКорректировкиИнформацииСопоставленияБезусловно(УзелОбменаЗагрузкаДанных);
		КонецЕсли;
		
		Если ЕстьИнформацияОРегистрацииОбъекта = Истина Тогда
			РегистрыСведений.СоответствияОбъектовИнформационныхБаз.УдалитьНеактуальныеЗаписиРежимаВыгрузкиПоСсылке(УзелОбменаЗагрузкаДанных);
		КонецЕсли;
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
	КонецПопытки;
	
	РазблокироватьДанныеДляРедактирования(ЧтениеСообщения.Отправитель);
	
КонецПроцедуры

Процедура ПрерватьЧтениеСообщения(Знач ЧтениеСообщения)
	
	ФайлОбмена.Закрыть();
	
	РазблокироватьДанныеДляРедактирования(ЧтениеСообщения.Отправитель);
	
КонецПроцедуры

Процедура ВыполнитьАлгоритмПослеЗагрузкиПараметров(Знач ТекстАлгоритма)
	
	Если ПустаяСтрока(ТекстАлгоритма) Тогда
		Возврат;
	КонецЕсли;
	
	Отказ = Ложь;
	ПричинаОтказа = "";
	
	Попытка
		
		Если ОтладкаОбработчиковЗагрузки Тогда
			
			ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиПараметров(ФайлОбмена, Отказ, ПричинаОтказа);
			
		Иначе
			
			Выполнить(ТекстАлгоритма);
			
		КонецЕсли;
		
		Если Отказ = Истина Тогда
			
			Если Не ПустаяСтрока(ПричинаОтказа) Тогда
				
				СтрокаСообщения = НСтр("ru = 'Отказ от загрузки сообщения обмена в обработчике ПослеЗагрузкиПараметров (конвертация) по причине: %1'");
				СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ПричинаОтказа);
				ВызватьИсключение СтрокаСообщения;
			Иначе
				ВызватьИсключение НСтр("ru = 'Отказ от загрузки сообщения обмена в обработчике ПослеЗагрузкиПараметров (конвертация).'");
			КонецЕсли;
			
		КонецЕсли;
		
	Исключение
		
		ЗП = ЗаписьПротоколаОбмена(78, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ЗП.Обработчик     = "ПослеЗагрузкиПараметров";
		СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(78, ЗП);
		
		Если Не ПродолжитьПриОшибке Тогда
			ВызватьИсключение СтрокаСообщенияОбОшибке;
		КонецЕсли;
		
	КонецПопытки;
	
КонецПроцедуры

Функция УстановитьСсылкуНового(Объект, Менеджер, СвойстваПоиска)
	
	УИ = СвойстваПоиска["{УникальныйИдентификатор}"];
	
	Если УИ <> Неопределено Тогда
		
		НоваяСсылка = Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(УИ));
		
		Объект.УстановитьСсылкуНового(НоваяСсылка);
		
		СвойстваПоиска.Удалить("{УникальныйИдентификатор}");
		
	Иначе
		
		Объект.УстановитьСсылкуНового(Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор));
		НоваяСсылка = Неопределено;
		
	КонецЕсли;
	
	Возврат НоваяСсылка;
	
КонецФункции

// Ищет объект по номеру в списке уже загруженных объектов.
//
// Параметры:
//  НПП          - номер искомого объекта в файле обмена.
//
// Возвращаемое значение:
//  Ссылка на найденный объект. Если объект не найден, возвращается Неопределено.
// 
Функция НайтиОбъектПоНомеру(НПП, ТипОбъекта, РежимПоискаОсновногоОбъекта = Ложь)
	
	Возврат Неопределено;
	
КонецФункции

Функция НайтиОбъектПоГлобальномуНомеру(НПП, РежимПоискаОсновногоОбъекта = Ложь)
	
	Возврат Неопределено;
	
КонецФункции

Процедура СнятьПометкуУдаленияСПредопределенногоЭлемента(Объект, Знач ТипОбъекта)
	
	Если ТипЗнч(ТипОбъекта) = ТипСтрока Тогда
		ТипОбъекта = Тип(ТипОбъекта);
	КонецЕсли;
	
	Если (Справочники.ТипВсеСсылки().СодержитТип(ТипОбъекта)
		Или ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(ТипОбъекта)
		Или ПланыСчетов.ТипВсеСсылки().СодержитТип(ТипОбъекта)
		Или ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(ТипОбъекта))
		И Объект.ПометкаУдаления
		И Объект.Предопределенный Тогда
		
		Объект.ПометкаУдаления = Ложь;
		
		// фиксируем событие в ЖР
		ЗП            = ЗаписьПротоколаОбмена(80);
		ЗП.ТипОбъекта = ТипОбъекта;
		ЗП.Объект     = Строка(Объект);
		
		ЗаписатьВПротоколВыполнения(80, ЗП, Ложь,,,,Перечисления.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура УстановитьТекущуюДатуРеквизиту(РеквизитОбъекта)
	
	РеквизитОбъекта = ТекущаяДатаСеанса();
	
КонецПроцедуры

// Создает новый объект указанного типа, устанавливает реквизиты, указанные
// в структуре СвойстваПоиска.
//
// Параметры:
//  Тип            - тип создаваемого объекта.
//  СвойстваПоиска - Структура - содержащая устанавливаемые реквизиты нового объекта.
//  Объект - объект информационной базы, созданный в результате выполнения.
//  ЗаписыватьОбъектСразуПослеСоздания - Булево
//  НоваяСсылка - ссылка на созданный объект.
//  УстанавливатьУОбъектаВсеСвойстваПоиска - Булево.
//  НаборЗаписейРегистра - РегистрСведенийНаборЗаписей - который создан.
//
// Возвращаемое значение:
//  Созданный объект, либо Неопределено (если не установлен ЗаписыватьОбъектСразуПослеСоздания).
// 
Функция СоздатьНовыйОбъект(Тип, СвойстваПоиска, Объект, 
	ЗаписыватьОбъектСразуПослеСоздания, НоваяСсылка = Неопределено, 
	УстанавливатьУОбъектаВсеСвойстваПоиска = Истина,
	НаборЗаписейРегистра = Неопределено)
	
	СвойстваМД      = Менеджеры[Тип];
	ИмяТипа         = СвойстваМД.ИмяТипа;
	Менеджер        = СвойстваМД.Менеджер;

	Если ИмяТипа = "Справочник"
		ИЛИ ИмяТипа = "ПланВидовХарактеристик" Тогда
		
		ЭтоГруппа = СвойстваПоиска["ЭтоГруппа"];
		
		Если ЭтоГруппа = Истина Тогда
			
			Объект = Менеджер.СоздатьГруппу();
						
		Иначе
			
			Объект = Менеджер.СоздатьЭлемент();
			
		КонецЕсли;		
				
	ИначеЕсли ИмяТипа = "Документ" Тогда
		
		Объект = Менеджер.СоздатьДокумент();
				
	ИначеЕсли ИмяТипа = "ПланСчетов" Тогда
		
		Объект = Менеджер.СоздатьСчет();
				
	ИначеЕсли ИмяТипа = "ПланВидовРасчета" Тогда
		
		Объект = Менеджер.СоздатьВидРасчета();
				
	ИначеЕсли ИмяТипа = "РегистрСведений" Тогда
		
		НаборЗаписейРегистра = Менеджер.СоздатьНаборЗаписей(); // РегистрСведенийНаборЗаписей
		Объект = НаборЗаписейРегистра.Добавить();
		Возврат Объект;
		
	ИначеЕсли ИмяТипа = "ПланОбмена" Тогда
		
		Объект = Менеджер.СоздатьУзел();
				
	ИначеЕсли ИмяТипа = "Задача" Тогда
		
		Объект = Менеджер.СоздатьЗадачу();
		
	ИначеЕсли ИмяТипа = "БизнесПроцесс" Тогда
		
		Объект = Менеджер.СоздатьБизнесПроцесс();	
		
	ИначеЕсли ИмяТипа = "Перечисление" Тогда
		
		Объект = СвойстваМД.ПустаяСсылка;	
		Возврат Объект;
		
	ИначеЕсли ИмяТипа = "ТочкаМаршрутаБизнесПроцесса" Тогда
		
		Возврат Неопределено;
				
	КонецЕсли;
	
	НоваяСсылка = УстановитьСсылкуНового(Объект, Менеджер, СвойстваПоиска);
	
	Если УстанавливатьУОбъектаВсеСвойстваПоиска Тогда
		УстановитьРеквизитыПоискаУОбъекта(Объект, СвойстваПоиска, , Ложь, Ложь);
	КонецЕсли;
	
	// Проверки
	Если ИмяТипа = "Документ"
		ИЛИ ИмяТипа = "Задача"
		ИЛИ ИмяТипа = "БизнесПроцесс" Тогда
		
		Если НЕ ЗначениеЗаполнено(Объект.Дата) Тогда
			
			УстановитьТекущуюДатуРеквизиту(Объект.Дата);			
						
		КонецЕсли;
		
	КонецЕсли;
		
	Если ЗаписыватьОбъектСразуПослеСоздания Тогда
		
		ЗаписатьОбъектВИБ(Объект, Тип);
		
	Иначе
		
		Возврат Неопределено;
		
	КонецЕсли;
	
	Возврат Объект.Ссылка;
	
КонецФункции

// Читает из файла узел свойства объекта, устанавливает значение свойства.
//
// Параметры:
//  Тип            - тип значения свойства.
//  ОбъектНайден   - если после выполнения функции - Ложь, то значит
//                   объект свойства не найден в информационной базе и создан новый.
//
// Возвращаемое значение:
//  Значение свойства
// 
Функция ПрочитатьСвойство(Тип, НеСоздаватьОбъектЕслиНеНайден = Ложь, СвойствоНеНайденоПоСсылке = Ложь, ИмяПКО = "")

	Значение = Неопределено;
	НаличиеСвойств = Ложь;
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
				
		Если ИмяУзла = "Значение" Тогда
			
			ИскатьПоСвойству = одАтрибут(ФайлОбмена, ТипСтрока, "Свойство");
			Значение         = одЗначениеЭлемента(ФайлОбмена, Тип, ИскатьПоСвойству, Ложь);
			НаличиеСвойств = Истина;
			
		ИначеЕсли ИмяУзла = "Ссылка" Тогда
			
			СоответствияОбъектовИнформационныхБаз = Неопределено;
			СозданныйОбъект = Неопределено;
			ОбъектНайден = Истина;
			ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли = Ложь;
			
			Значение = НайтиОбъектПоСсылке(Тип,
											,
											, 
											ОбъектНайден, 
											СозданныйОбъект, 
											НеСоздаватьОбъектЕслиНеНайден, 
											, 
											, 
											, 
											, 
											, 
											, 
											, 
											, 
											, 
											, 
											, 
											ИмяПКО, 
											СоответствияОбъектовИнформационныхБаз, 
											ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли);
			
			Если НеСоздаватьОбъектЕслиНеНайден
				И НЕ ОбъектНайден Тогда
				
				СвойствоНеНайденоПоСсылке = Ложь;
				
			КонецЕсли;
			
			НаличиеСвойств = Истина;
			
		ИначеЕсли ИмяУзла = "Нпп" Тогда
			
			ФайлОбмена.Прочитать();
			НПП = Число(ФайлОбмена.Значение);
			Если НПП <> 0 Тогда
				Значение  = НайтиОбъектПоНомеру(НПП, Тип);
				НаличиеСвойств = Истина;
			КонецЕсли;			
			ФайлОбмена.Прочитать();
			
		ИначеЕсли ИмяУзла = "ГНпп" Тогда
			
			ФайлОбмена.Прочитать();
			ГНПП = Число(ФайлОбмена.Значение);
			Если ГНПП <> 0 Тогда
				Значение  = НайтиОбъектПоГлобальномуНомеру(ГНПП);
				НаличиеСвойств = Истина;
			КонецЕсли;
			
			ФайлОбмена.Прочитать();
			
		ИначеЕсли (ИмяУзла = "Свойство" ИЛИ ИмяУзла = "ЗначениеПараметра") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Если Не НаличиеСвойств
				И ЗначениеЗаполнено(Тип) Тогда
				
				// Если вообще ничего нет - значит пустое значение.
				Значение = одПолучитьПустоеЗначение(Тип);
				
			КонецЕсли;
			
			Прервать;
			
		ИначеЕсли ИмяУзла = "Выражение" Тогда
			
			Выражение = одЗначениеЭлемента(ФайлОбмена, ТипСтрока, , Ложь);
			Значение  = ОбщегоНазначения.ВычислитьВБезопасномРежиме(Выражение);
			
			НаличиеСвойств = Истина;
			
		ИначеЕсли ИмяУзла = "Пусто" Тогда
			
			Значение = одПолучитьПустоеЗначение(Тип);
			НаличиеСвойств = Истина;
			
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Значение;
	
КонецФункции

Процедура УстановитьРеквизитыПоискаУОбъекта(НайденныйОбъект, СвойстваПоиска,
		СвойстваПоискаНеЗамещать = Неопределено, НужноСравниватьСТекущимиРеквизитами = Истина, НЕЗаменятьСвойстваНеПодлежащиеИзменению = Истина)
	
	Для каждого Свойство Из СвойстваПоиска Цикл
					
		Имя      = Свойство.Ключ;
		Значение = Свойство.Значение;
		
		Если НЕЗаменятьСвойстваНеПодлежащиеИзменению
			И СвойстваПоискаНеЗамещать[Имя] <> Неопределено Тогда
			
			Продолжить;
			
		КонецЕсли;
					
		Если Имя = "ЭтоГруппа" 
			ИЛИ Имя = "{УникальныйИдентификатор}" 
			ИЛИ Имя = "{ИмяПредопределенногоЭлемента}"
			ИЛИ Имя = "{КлючПоискаВИБИсточнике}"
			ИЛИ Имя = "{КлючПоискаВИБПриемнике}"
			ИЛИ Имя = "{ИмяТипаВИБИсточнике}"
			ИЛИ Имя = "{ИмяТипаВИБПриемнике}" Тогда
						
			Продолжить;
						
		ИначеЕсли Имя = "ПометкаУдаления" Тогда
						
			Если НЕ НужноСравниватьСТекущимиРеквизитами
				ИЛИ НайденныйОбъект.ПометкаУдаления <> Значение Тогда
							
				НайденныйОбъект.ПометкаУдаления = Значение;
							
			КонецЕсли;
						
		Иначе
				
			// Отличные реквизиты устанавливаем.
			
			Если НайденныйОбъект[Имя] <> NULL Тогда
			
				Если НЕ НужноСравниватьСТекущимиРеквизитами
					ИЛИ НайденныйОбъект[Имя] <> Значение Тогда
						
					НайденныйОбъект[Имя] = Значение;
					
						
				КонецЕсли;
				
			КонецЕсли;
				
		КонецЕсли;
					
	КонецЦикла;
	
КонецПроцедуры

Функция НайтиИлиСоздатьОбъектПоСвойству(СтруктураСвойств,
									ТипОбъекта,
									СвойстваПоиска,
									СвойстваПоискаНеЗамещать,
									ИмяТипаОбъекта,
									СвойствоПоиска,
									ЗначениеСвойстваПоиска,
									ОбъектНайден,
									СоздаватьНовыйЭлементЕслиНеНайден = Истина,
									НайденныйИлиСозданныйОбъект = Неопределено,
									РежимПоискаОсновногоОбъекта = Ложь,
									НоваяСсылкаУникальногоИдентификатора = Неопределено,
									НПП = 0,
									ГНПП = 0,
									ПараметрыОбъекта = Неопределено,
									НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = Ложь,
									ОбъектБылСозданВТекущейИнформационнойБазе = Неопределено)
	
	Объект = одНайтиОбъектПоСвойству(СтруктураСвойств.Менеджер, СвойствоПоиска, ЗначениеСвойстваПоиска, 
		НайденныйИлиСозданныйОбъект, , , РежимПоискаОсновногоОбъекта, СтруктураСвойств.СтрокаПоиска);
	
	ОбъектНайден = НЕ (Объект = Неопределено
				ИЛИ Объект.Пустая());
				
	Если Не ОбъектНайден
		И СоздаватьНовыйЭлементЕслиНеНайден Тогда
		
		Объект = СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, НайденныйИлиСозданныйОбъект, 
			НЕ РежимПоискаОсновногоОбъекта, НоваяСсылкаУникальногоИдентификатора);
			
		Возврат Объект;
		
	КонецЕсли;
			
	
	Если РежимПоискаОсновногоОбъекта Тогда
		
		//
		Попытка
			
			Если Не ЗначениеЗаполнено(Объект) Тогда
				Возврат Объект;
			КонецЕсли;
			
			Если НайденныйИлиСозданныйОбъект = Неопределено Тогда
				НайденныйИлиСозданныйОбъект = Объект.ПолучитьОбъект();
			КонецЕсли;
			
		Исключение
			Возврат Объект;
		КонецПопытки;
			
		УстановитьРеквизитыПоискаУОбъекта(НайденныйИлиСозданныйОбъект, СвойстваПоиска, СвойстваПоискаНеЗамещать);
		
	КонецЕсли;
		
	Возврат Объект;
	
КонецФункции

Функция ТипСвойства()
	
	СтроковыйТипСвойства = одАтрибут(ФайлОбмена, ТипСтрока, "Тип");
	Если ПустаяСтрока(СтроковыйТипСвойства) Тогда
		
		// Нужно определять свойство по соответствию.
		Возврат Неопределено;
		
	ИначеЕсли СтроковыйТипСвойства = "ОпределениеТипа" Тогда
		
		Возврат Тип("ОписаниеТипов");
		
	КонецЕсли;
	
	Возврат Тип(СтроковыйТипСвойства);
	
КонецФункции

Функция ТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, ИмяСвойства)
	
	ТипСвойства = ТипСвойства();
				
	Если ТипСвойства = Неопределено
		И ИнформацияОТипах <> Неопределено Тогда
		
		ТипСвойства = ИнформацияОТипах[ИмяСвойства];
		
	КонецЕсли;
	
	Возврат ТипСвойства;
	
КонецФункции

Процедура ПрочитатьСвойстваПоискаИзФайла(СвойстваПоиска, СвойстваПоискаНеЗамещать, ИнформацияОТипах,
	ПоискПоДатеНаРавенство, ПараметрыОбъекта, Знач РежимПоискаОсновногоОбъекта, НайденоСоответствиеОбъекта, СоответствияОбъектовИнформационныхБаз)
	
	ПоискПоДатеНаРавенство = Ложь;
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
				
		Если    ИмяУзла = "Свойство"
			ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда
			
			ЭтоПараметр = (ИмяУзла = "ЗначениеПараметра");
			
			Имя = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
			
			ТипИсточникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипПриемника");
			ТипПриемникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипИсточника");
			
			СвойствоУникальныйИдентификатор = (Имя = "{УникальныйИдентификатор}");
			
			Если СвойствоУникальныйИдентификатор Тогда
				
				ТипСвойства = ТипСтрока;
				
			ИначеЕсли Имя = "{ИмяПредопределенногоЭлемента}"
				  ИЛИ Имя = "{КлючПоискаВИБИсточнике}"
				  ИЛИ Имя = "{КлючПоискаВИБПриемнике}"
				  ИЛИ Имя = "{ИмяТипаВИБИсточнике}"
				  ИЛИ Имя = "{ИмяТипаВИБПриемнике}" Тогда
				
				ТипСвойства = ТипСтрока;
				
			Иначе
				
				ТипСвойства = ТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя);
				
			КонецЕсли;
			
			НеЗамещатьСвойство = одАтрибут(ФайлОбмена, ТипБулево, "НеЗамещать");
			
			ПоискПоДатеНаРавенство = ПоискПоДатеНаРавенство 
						ИЛИ одАтрибут(ФайлОбмена, ТипБулево, "ПоискПоДатеНаРавенство");
			//
			ИмяПКО = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПКО");
			
			ЗначениеСвойства = ПрочитатьСвойство(ТипСвойства,,, ИмяПКО);
			
			Если СвойствоУникальныйИдентификатор Тогда
				
				ВыполнитьЗаменуУникальногоИдентификатораПриНеобходимости(ЗначениеСвойства, ТипИсточникаСтрокой, ТипПриемникаСтрокой, РежимПоискаОсновногоОбъекта, НайденоСоответствиеОбъекта, СоответствияОбъектовИнформационныхБаз);
				
			КонецЕсли;
			
			Если (Имя = "ЭтоГруппа") И (ЗначениеСвойства <> Истина) Тогда
				
				ЗначениеСвойства = Ложь;
												
			КонецЕсли; 
			
			Если ЭтоПараметр Тогда
				
				
				ДобавитьПараметрПриНеобходимости(ПараметрыОбъекта, Имя, ЗначениеСвойства);
				
			Иначе
			
				СвойстваПоиска[Имя] = ЗначениеСвойства;
				
				Если НеЗамещатьСвойство Тогда
					
					СвойстваПоискаНеЗамещать[Имя] = Истина;
					
				КонецЕсли;
				
			КонецЕсли;
			
		ИначеЕсли (ИмяУзла = "Ссылка") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры

Процедура ВыполнитьЗаменуУникальногоИдентификатораПриНеобходимости(
										УникальныйИдентификатор,
										Знач ТипИсточникаСтрокой,
										Знач ТипПриемникаСтрокой,
										Знач РежимПоискаОсновногоОбъекта,
										НайденоСоответствиеОбъекта = Ложь,
										СоответствияОбъектовИнформационныхБаз = Неопределено)
	
	// В режиме сопоставления для основных объектов замену не выполняем.
	Если РежимПоискаОсновногоОбъекта И РежимЗагрузкиДанныхВТаблицуЗначений() Тогда
		Возврат;
	КонецЕсли;
	
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("УзелИнформационнойБазы", УзелОбменаЗагрузкаДанных);
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("УникальныйИдентификаторПриемника", УникальныйИдентификатор);
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("ТипПриемника", ТипПриемникаСтрокой);
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("ТипИсточника", ТипИсточникаСтрокой);
	
	РезультатЗапроса = ЗапросСоответствияОбъектовИнформационныхБаз.Выполнить();
	
	Если РезультатЗапроса.Пустой() Тогда
		
		СоответствияОбъектовИнформационныхБаз = Новый Структура;
		СоответствияОбъектовИнформационныхБаз.Вставить("УзелИнформационнойБазы", УзелОбменаЗагрузкаДанных);
		СоответствияОбъектовИнформационныхБаз.Вставить("ТипПриемника", ТипПриемникаСтрокой);
		СоответствияОбъектовИнформационныхБаз.Вставить("ТипИсточника", ТипИсточникаСтрокой);
		СоответствияОбъектовИнформационныхБаз.Вставить("УникальныйИдентификаторПриемника", УникальныйИдентификатор);
		
		// Значение будет определено после записи объекта.
		// Возможно, объекту будет назначено сопоставление при идентификации объекта по полям поиска.
		СоответствияОбъектовИнформационныхБаз.Вставить("УникальныйИдентификаторИсточника", Неопределено);
		
	Иначе
		
		Выборка = РезультатЗапроса.Выбрать();
		Выборка.Следующий();
		
		УникальныйИдентификатор = Выборка.УникальныйИдентификаторИсточникаСтрокой;
		
		НайденоСоответствиеОбъекта = Истина;
		
	КонецЕсли;
	
КонецПроцедуры

Функция ОпределитьУПоляНеограниченнаяДлина(МенеджерТипа, ИмяПараметра)
	
	ДлинныеСтроки = Неопределено;
	Если НЕ МенеджерТипа.Свойство("ДлинныеСтроки", ДлинныеСтроки) Тогда
		
		ДлинныеСтроки = Новый Соответствие;
		Для Каждого Реквизит Из МенеджерТипа.ОбъектМД.Реквизиты Цикл
			
			Если Реквизит.Тип.СодержитТип(ТипСтрока) 
				И (Реквизит.Тип.КвалификаторыСтроки.Длина = 0) Тогда
				
				ДлинныеСтроки.Вставить(Реквизит.Имя, Реквизит.Имя);	
				
			КонецЕсли;
			
		КонецЦикла;
		
		МенеджерТипа.Вставить("ДлинныеСтроки", ДлинныеСтроки);
		
	КонецЕсли;
	
	Возврат (ДлинныеСтроки[ИмяПараметра] <> Неопределено);
		
КонецФункции

Функция ОпределитьЭтотПараметрНеограниченнойДлинны(МенеджерТипа, ЗначениеПараметра, ИмяПараметра)
	
	Если ТипЗнч(ЗначениеПараметра) = ТипСтрока Тогда
		СтрокаНеограниченнойДлины = ОпределитьУПоляНеограниченнаяДлина(МенеджерТипа, ИмяПараметра);
	Иначе
		СтрокаНеограниченнойДлины = Ложь;
	КонецЕсли;
	
	Возврат СтрокаНеограниченнойДлины;
	
КонецФункции

Функция НайтиЭлементЗапросом(СтруктураСвойств, СвойстваПоиска, ТипОбъекта = Неопределено, 
	МенеджерТипа = Неопределено, КоличествоРеальныхСвойствДляПоиска = Неопределено)
	
	КоличествоСвойствДляПоиска = ?(КоличествоРеальныхСвойствДляПоиска = Неопределено, СвойстваПоиска.Количество(), КоличествоРеальныхСвойствДляПоиска);
	
	Если КоличествоСвойствДляПоиска = 0
		И СтруктураСвойств.ИмяТипа = "Перечисление" Тогда
		
		Возврат СтруктураСвойств.ПустаяСсылка;
		
	КонецЕсли;
	
	ТекстЗапроса       = СтруктураСвойств.СтрокаПоиска;
	
	Если ПустаяСтрока(ТекстЗапроса) Тогда
		Возврат СтруктураСвойств.ПустаяСсылка;
	КонецЕсли;
	
	ЗапросПоиска       = Новый Запрос();
	
	КоличествоСвойствПоКоторымУстановленПоиск = 0;
	
	Для Каждого Свойство Из СвойстваПоиска Цикл
		
		ИмяПараметра = Свойство.Ключ;
		
		// Не по всем параметрам можно искать.
		Если ИмяПараметра = "{УникальныйИдентификатор}" Или ИмяПараметра = "{ИмяПредопределенногоЭлемента}" Тогда
			Продолжить;
		КонецЕсли;
		
		ЗначениеПараметра = Свойство.Значение;
		ЗапросПоиска.УстановитьПараметр(ИмяПараметра, ЗначениеПараметра);
		
		СтрокаНеограниченнойДлины = ОпределитьЭтотПараметрНеограниченнойДлинны(СтруктураСвойств, ЗначениеПараметра, ИмяПараметра);
		
		КоличествоСвойствПоКоторымУстановленПоиск = КоличествоСвойствПоКоторымУстановленПоиск + 1;
		
		Если СтрокаНеограниченнойДлины Тогда
			
			ТекстЗапроса = ТекстЗапроса + ?(КоличествоСвойствПоКоторымУстановленПоиск > 1, " И ", "") + ИмяПараметра + " ПОДОБНО &" + ИмяПараметра;
			
		Иначе
			
			ТекстЗапроса = ТекстЗапроса + ?(КоличествоСвойствПоКоторымУстановленПоиск > 1, " И ", "") + ИмяПараметра + " = &" + ИмяПараметра;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Если КоличествоСвойствПоКоторымУстановленПоиск = 0 Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ЗапросПоиска.Текст = ТекстЗапроса;
	Результат = ЗапросПоиска.Выполнить();
			
	Если Результат.Пустой() Тогда
		
		Возврат Неопределено;
								
	Иначе
		
		// Возвращаем первый найденный объект.
		Выборка = Результат.Выбрать();
		Выборка.Следующий();
		СсылкаНаОбъект = Выборка.Ссылка;
				
	КонецЕсли;
	
	Возврат СсылкаНаОбъект;
	
КонецФункции

// Определяет по типу объекта приемника правило конвертации объекта (ПКО).
//
// Параметры:
//  ТипСсылкиСтрокой - Строка - тип объекта в строковом представлении, например, "СправочникСсылка.Номенклатура".
// 
// Возвращаемое значение:
//  ЗначениеСоответствия = Правило конвертации объекта.
// 
Функция ОпределитьПоТипуОбъектаПриемникаПравилоКонвертацииКотороеСодержитАлгоритмПоиска(ТипСсылкиСтрокой)
	
	ЗначениеСоответствия = СоответствиеПравилКонвертации.Получить(ТипСсылкиСтрокой);
	
	Если ЗначениеСоответствия <> Неопределено Тогда
		Возврат ЗначениеСоответствия;
	КонецЕсли;
	
	Попытка
	
		Для Каждого Элемент Из Правила Цикл
			
			Если Элемент.Значение.Приемник = ТипСсылкиСтрокой Тогда
				
				Если Элемент.Значение.ЕстьОбработчикПоследовательностьПолейПоиска = Истина Тогда
					
					Правило = Элемент.Значение;
					
					СоответствиеПравилКонвертации.Вставить(ТипСсылкиСтрокой, Правило);
					
					Возврат Правило;
					
				КонецЕсли;
				
			КонецЕсли;
			
		КонецЦикла;
		
		СоответствиеПравилКонвертации.Вставить(ТипСсылкиСтрокой, Неопределено);
		Возврат Неопределено;
	
	Исключение
		
		СоответствиеПравилКонвертации.Вставить(ТипСсылкиСтрокой, Неопределено);
		Возврат Неопределено;
	
	КонецПопытки;
	
КонецФункции

Функция НайтиСсылкуНаДокумент(СвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом, ПоискПоДатеНаРавенство)
	
	// Попробуем документ по дате и номеру найти.
	ИскатьЗапросом = ПоискПоДатеНаРавенство ИЛИ (КоличествоРеальныхСвойствДляПоиска <> 2);
				
	Если ИскатьЗапросом Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	НомерДокумента = СвойстваПоиска["Номер"];
	ДатаДокумента  = СвойстваПоиска["Дата"];
					
	Если (НомерДокумента <> Неопределено) И (ДатаДокумента <> Неопределено) Тогда
						
		СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНомеру(НомерДокумента, ДатаДокумента);
																		
	Иначе
						
		// По дате и номеру найти не удалось - надо искать запросом.
		ИскатьЗапросом = Истина;
		СсылкаНаОбъект = Неопределено;
						
	КонецЕсли;
	
	Возврат СсылкаНаОбъект;
	
КонецФункции

Функция НайтиЭлементПоСвойствамПоиска(ТипОбъекта, ИмяТипаОбъекта, СвойстваПоиска, 
	СтруктураСвойств, СтрокаИменСвойствПоиска, ПоискПоДатеНаРавенство)
	
	// Не нужно искать по имени предопределенного элемента и по уникальной ссылке на объект
	// нужно искать только по тем свойствам, которые имеются в строке имен свойств. Если там пусто, то по
	// всем имеющимся свойствам поиска.
	
	Если ПустаяСтрока(СтрокаИменСвойствПоиска) Тогда
		
		ВременныеСвойстваПоиска = СвойстваПоиска;
		
	Иначе
		
		ВыбранныеСвойства = СтрРазделить(СтрокаИменСвойствПоиска, ", ", Ложь);
		
		ВременныеСвойстваПоиска = Новый Соответствие;
		Для Каждого ЭлементСвойств Из СвойстваПоиска Цикл
			
			Если ВыбранныеСвойства.Найти(ЭлементСвойств.Ключ) <> Неопределено Тогда
				ВременныеСвойстваПоиска.Вставить(ЭлементСвойств.Ключ, ЭлементСвойств.Значение);
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЕсли;
	
	СвойствоУникальныйИдентификатор = ВременныеСвойстваПоиска["{УникальныйИдентификатор}"];
	СвойствоИмяПредопределенного    = ВременныеСвойстваПоиска["{ИмяПредопределенногоЭлемента}"];
	
	КоличествоРеальныхСвойствДляПоиска = ВременныеСвойстваПоиска.Количество();
	КоличествоРеальныхСвойствДляПоиска = КоличествоРеальныхСвойствДляПоиска - ?(СвойствоУникальныйИдентификатор <> Неопределено, 1, 0);
	КоличествоРеальныхСвойствДляПоиска = КоличествоРеальныхСвойствДляПоиска - ?(СвойствоИмяПредопределенного    <> Неопределено, 1, 0);
	
	ИскатьЗапросом = Ложь;
	
	Если ИмяТипаОбъекта = "Документ" Тогда
		
		СсылкаНаОбъект = НайтиСсылкуНаДокумент(ВременныеСвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом, ПоискПоДатеНаРавенство);
		
	Иначе
		
		ИскатьЗапросом = Истина;
		
	КонецЕсли;
	
	Если ИскатьЗапросом Тогда
		
		СсылкаНаОбъект = НайтиЭлементЗапросом(СтруктураСвойств, ВременныеСвойстваПоиска, ТипОбъекта, , КоличествоРеальныхСвойствДляПоиска);
		
	КонецЕсли;
	
	Возврат СсылкаНаОбъект;
КонецФункции

Процедура ОбработатьУстановкуСвойствПоискаУОбъекта(УстанавливатьУОбъектаВсеСвойстваПоиска, 
												ТипОбъекта, 
												СвойстваПоиска, 
												СвойстваПоискаНеЗамещать, 
												СсылкаНаОбъект, 
												СозданныйОбъект, 
												ЗаписыватьНовыйОбъектВИнформационнуюБазу = Истина, 
												НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = Ложь, 
												ОбъектБылСозданВТекущейИнформационнойБазе = Неопределено)
	
	Если УстанавливатьУОбъектаВсеСвойстваПоиска <> Истина Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
		Возврат;
	КонецЕсли;
	
	Если СозданныйОбъект = Неопределено Тогда
		СозданныйОбъект = СсылкаНаОбъект.ПолучитьОбъект();
	КонецЕсли;
	
	УстановитьРеквизитыПоискаУОбъекта(СозданныйОбъект, СвойстваПоиска, СвойстваПоискаНеЗамещать);
	
КонецПроцедуры

Процедура ПрочитатьИнформациюОСвойствахПоиска(ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать,
	ПоискПоДатеНаРавенство = Ложь, ПараметрыОбъекта = Неопределено, Знач РежимПоискаОсновногоОбъекта, НайденоСоответствиеОбъекта, СоответствияОбъектовИнформационныхБаз)
	
	Если СвойстваПоиска = "" Тогда
		СвойстваПоиска = Новый Соответствие;
	КонецЕсли;
	
	Если СвойстваПоискаНеЗамещать = "" Тогда
		СвойстваПоискаНеЗамещать = Новый Соответствие;
	КонецЕсли;
	
	ИнформацияОТипах = СоответствиеТиповДанныхДляЗагрузки()[ТипОбъекта];
	ПрочитатьСвойстваПоискаИзФайла(СвойстваПоиска, СвойстваПоискаНеЗамещать, ИнформацияОТипах, ПоискПоДатеНаРавенство, ПараметрыОбъекта, РежимПоискаОсновногоОбъекта, НайденоСоответствиеОбъекта, СоответствияОбъектовИнформационныхБаз);
	
КонецПроцедуры

Процедура ОпределитьДополнительныеПараметрыПоискаОбъекта(СвойстваПоиска, ТипОбъекта, СтруктураСвойств, ИмяТипаОбъекта, ЭтоОбъектДокумент)
	
	Если ТипОбъекта = Неопределено Тогда
		
		// Попробуем определить тип по свойствам поиска.
		ИмяТипаПриемника = СвойстваПоиска["{ИмяТипаВИБПриемнике}"];
		Если ИмяТипаПриемника = Неопределено Тогда
			ИмяТипаПриемника = СвойстваПоиска["{ИмяТипаВИБИсточнике}"];
		КонецЕсли;
		
		Если ИмяТипаПриемника <> Неопределено Тогда
			
			ТипОбъекта = Тип(ИмяТипаПриемника);	
			
		КонецЕсли;		
		
	КонецЕсли;
	
	СтруктураСвойств   = Менеджеры[ТипОбъекта];
	ИмяТипаОбъекта     = СтруктураСвойств.ИмяТипа;	
	
КонецПроцедуры

// Производит поиск объекта в информационной базе, если не найден создает новый.
//
// Параметры:
//  ТипОбъекта     - тип искомого объекта.
//  СвойстваПоиска - Структура - содержащая свойства по которым производится поиск объекта.
//  ОбъектНайден   - если Ложь, то объект не найден, а создан новый.
//
// Возвращаемое значение:
//  Новый или найденный объект информационной базы.
//  
Функция НайтиОбъектПоСсылке(ТипОбъекта, 
							СвойстваПоиска = "", 
							СвойстваПоискаНеЗамещать = "", 
							ОбъектНайден = Истина, 
							СозданныйОбъект = Неопределено, 
							НеСоздаватьОбъектЕслиНеНайден = Ложь,
							РежимПоискаОсновногоОбъекта = Ложь,
							НППГлобальнойСсылки = 0,
							НППСсылки = 0,
							ОбъектНайденПоПолямПоиска = Ложь,
							ИзвестнаяСсылкаУникальногоИдентификатора = Неопределено,
							ЭтоПоискОбъектаЗагрузки = Ложь,
							ПараметрыОбъекта = Неопределено,
							НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = Ложь,
							ОбъектБылСозданВТекущейИнформационнойБазе = Неопределено,
							РегистрироватьОбъектНаУзлеОтправителе = Ложь,
							УникальныйИдентификаторСтрокой = "",
							ИмяПКО = "",
							СоответствияОбъектовИнформационныхБаз = Неопределено,
							ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли = Неопределено)
	
	// Идентификация объекта выполняется последовательно в пять этапов.
	// Переход к каждому последующему этапу выполняется в случае,
	// если поиск не дал положительного результата.
	//
	// Этапы идентификации (поиска) объекта:
	// 1. Поиск объекта по регистру сопоставления объектов ИБ.
	// 2. Поиск объекта по имени предопределенного элемента.
	// 3. Поиск объекта по уникальному идентификатору ссылки.
	// 4. Поиск объекта по произвольному алгоритму поиска.
	// 5. Поиск объекта по полям поиска.
	
	ПоискПоДатеНаРавенство = Ложь;
	СсылкаНаОбъект = Неопределено;
	СтруктураСвойств = Неопределено;
	ИмяТипаОбъекта = Неопределено;
	ЭтоОбъектДокумент = Ложь;
	ЧтениеСвойствСсылкиВыполнено = Ложь;
	НайденоСоответствиеОбъекта = Ложь;
	
	НППГлобальнойСсылки = одАтрибут(ФайлОбмена, ТипЧисло, "ГНпп");
	НППСсылки           = одАтрибут(ФайлОбмена, ТипЧисло, "Нпп");
	
	// Признак того, что объект необходимо зарегистрировать к выгрузке для узла-отправителя (отправка объекта назад).
	РегистрироватьОбъектНаУзлеОтправителе = одАтрибут(ФайлОбмена, ТипБулево, "РегистрироватьОбъектНаУзлеОтправителе");
	
	ФлагНеСоздаватьОбъектЕслиНеНайден = одАтрибут(ФайлОбмена, ТипБулево, "НеСоздаватьЕслиНеНайден");
	Если НЕ ЗначениеЗаполнено(ФлагНеСоздаватьОбъектЕслиНеНайден) Тогда
		ФлагНеСоздаватьОбъектЕслиНеНайден = Ложь;
	КонецЕсли;
	
	Если НеСоздаватьОбъектЕслиНеНайден = Неопределено Тогда
		НеСоздаватьОбъектЕслиНеНайден = Ложь;
	КонецЕсли;
	
	ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD = НЕ РежимПоискаОсновногоОбъекта;
		
	НеСоздаватьОбъектЕслиНеНайден = НеСоздаватьОбъектЕслиНеНайден ИЛИ ФлагНеСоздаватьОбъектЕслиНеНайден;
	
	ФлагНеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = одАтрибут(ФайлОбмена, ТипБулево, "НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике");
	Если НЕ ЗначениеЗаполнено(ФлагНеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике) Тогда
		НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = Ложь;
	Иначе
		НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = ФлагНеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике;	
	КонецЕсли;
	
	ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли = одАтрибут(ФайлОбмена, ТипБулево, "ПродолжитьПоиск");
	
	// 1. Поиск объекта по регистру сопоставления объектов ИБ.
	ПрочитатьИнформациюОСвойствахПоиска(ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, ПоискПоДатеНаРавенство, ПараметрыОбъекта, РежимПоискаОсновногоОбъекта, НайденоСоответствиеОбъекта, СоответствияОбъектовИнформационныхБаз);
	ОпределитьДополнительныеПараметрыПоискаОбъекта(СвойстваПоиска, ТипОбъекта, СтруктураСвойств, ИмяТипаОбъекта, ЭтоОбъектДокумент);
	
	СвойствоУникальныйИдентификатор = СвойстваПоиска["{УникальныйИдентификатор}"];
	СвойствоИмяПредопределенного    = СвойстваПоиска["{ИмяПредопределенногоЭлемента}"];
	
	УникальныйИдентификаторСтрокой = СвойствоУникальныйИдентификатор;
	
	ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD = ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD
									И СвойствоУникальныйИдентификатор <> Неопределено;
	
	Если НайденоСоответствиеОбъекта Тогда
		
		// 1. Поиск объекта по регистру сопоставления объектов ИБ дал положительный результат.
		
		СсылкаНаОбъект = СтруктураСвойств.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(СвойствоУникальныйИдентификатор));
		
		Если РежимПоискаОсновногоОбъекта Тогда
			
			СозданныйОбъект = СсылкаНаОбъект.ПолучитьОбъект();
			
			Если СозданныйОбъект <> Неопределено Тогда
				
				УстановитьРеквизитыПоискаУОбъекта(СозданныйОбъект, СвойстваПоиска, СвойстваПоискаНеЗамещать);
				
				ОбъектНайден = Истина;
				
				Возврат СсылкаНаОбъект;
				
			КонецЕсли;
			
		Иначе
			
			// Для неосновных объектов (выгруженных по ссылке) просто получаем ссылку с заданным GUID.
			Возврат СсылкаНаОбъект;
			
		КонецЕсли;
		
	КонецЕсли;
	
	// 2. Поиск объекта имени предопределенного элемента.
	Если СвойствоИмяПредопределенного <> Неопределено Тогда
		
		АвтоматическиСоздаватьНовыйОбъект = Ложь;
		
		СсылкаНаОбъект = НайтиИлиСоздатьОбъектПоСвойству(СтруктураСвойств,
													ТипОбъекта,
													СвойстваПоиска,
													СвойстваПоискаНеЗамещать,
													ИмяТипаОбъекта,
													"{ИмяПредопределенногоЭлемента}",
													СвойствоИмяПредопределенного,
													ОбъектНайден,
													АвтоматическиСоздаватьНовыйОбъект,
													СозданныйОбъект,
													РежимПоискаОсновногоОбъекта,
													,
													НППСсылки, НППГлобальнойСсылки,
													ПараметрыОбъекта,
													НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике,
													ОбъектБылСозданВТекущейИнформационнойБазе);
		
		Если СсылкаНаОбъект <> Неопределено
			И СсылкаНаОбъект.Пустая() Тогда
			
			ОбъектНайден = Ложь;
			СсылкаНаОбъект = Неопределено;
					
		КонецЕсли;
			
		Если    СсылкаНаОбъект <> Неопределено
			ИЛИ СозданныйОбъект <> Неопределено Тогда
			
			ОбъектНайден = Истина;
			
			// 2. Поиск объекта имени предопределенного элемента дал положительный результат.
			Возврат СсылкаНаОбъект;
			
		КонецЕсли;
		
	КонецЕсли;
	
	// 3. Поиск объекта по уникальному идентификатору ссылки.
	Если СвойствоУникальныйИдентификатор <> Неопределено Тогда
		
		Если РежимПоискаОсновногоОбъекта Тогда
			
			АвтоматическиСоздаватьНовыйОбъект = НЕ НеСоздаватьОбъектЕслиНеНайден И Не ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли;
			
			СсылкаНаОбъект = НайтиИлиСоздатьОбъектПоСвойству(СтруктураСвойств,
														ТипОбъекта,
														СвойстваПоиска,
														СвойстваПоискаНеЗамещать,
														ИмяТипаОбъекта,
														"{УникальныйИдентификатор}",
														СвойствоУникальныйИдентификатор,
														ОбъектНайден,
														АвтоматическиСоздаватьНовыйОбъект,
														СозданныйОбъект,
														РежимПоискаОсновногоОбъекта,
														ИзвестнаяСсылкаУникальногоИдентификатора,
														НППСсылки,
														НППГлобальнойСсылки,
														ПараметрыОбъекта,
														НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике,
														ОбъектБылСозданВТекущейИнформационнойБазе);
			Если Не ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли Тогда
				
				Возврат СсылкаНаОбъект;
				
			КонецЕсли;
			
		ИначеЕсли ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли Тогда
			
			АвтоматическиСоздаватьНовыйОбъект = Ложь;
			
			СсылкаНаОбъект = НайтиИлиСоздатьОбъектПоСвойству(СтруктураСвойств,
														ТипОбъекта,
														СвойстваПоиска,
														СвойстваПоискаНеЗамещать,
														ИмяТипаОбъекта,
														"{УникальныйИдентификатор}",
														СвойствоУникальныйИдентификатор,
														ОбъектНайден,
														АвтоматическиСоздаватьНовыйОбъект,
														СозданныйОбъект,
														РежимПоискаОсновногоОбъекта,
														ИзвестнаяСсылкаУникальногоИдентификатора,
														НППСсылки,
														НППГлобальнойСсылки,
														ПараметрыОбъекта,
														НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике,
														ОбъектБылСозданВТекущейИнформационнойБазе);
			
		Иначе
			
			// Для неосновных объектов (выгруженных по ссылке) просто получаем ссылку с заданным GUID.
			Возврат СтруктураСвойств.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(СвойствоУникальныйИдентификатор));
			
		КонецЕсли;
		
		Если СсылкаНаОбъект <> Неопределено 
			И СсылкаНаОбъект.Пустая() Тогда
			
			ОбъектНайден = Ложь;
			СсылкаНаОбъект = Неопределено;
					
		КонецЕсли;
			
		Если    СсылкаНаОбъект <> Неопределено
			ИЛИ СозданныйОбъект <> Неопределено Тогда
			
			ОбъектНайден = Истина;
			
			// 3. Поиск объекта по уникальному идентификатору ссылки дал положительный результат.
			Возврат СсылкаНаОбъект;
			
		КонецЕсли;
		
	КонецЕсли;
	
	// 4. Поиск объекта по произвольному алгоритму поиска.
	НомерВариантаПоиска = 1;
	СтрокаИменСвойствПоиска = "";
	ПредыдущаяСтрокаПоиска = Неопределено;
	ПрекратитьПоиск = Ложь;
	УстанавливатьУОбъектаВсеСвойстваПоиска = Истина;
	ПКО = Неопределено;
	АлгоритмПоиска = "";
	
	Если Не ПустаяСтрока(ИмяПКО) Тогда
		
		ПКО = Правила[ИмяПКО];
		
	КонецЕсли;
	
	Если ПКО = Неопределено Тогда
		
		ПКО = ОпределитьПоТипуОбъектаПриемникаПравилоКонвертацииКотороеСодержитАлгоритмПоиска(СтруктураСвойств.ТипСсылкиСтрокой);
		
	КонецЕсли;
	
	Если ПКО <> Неопределено Тогда
		
		АлгоритмПоиска = ПКО.ПоследовательностьПолейПоиска;
		
	КонецЕсли;
	
	ЕстьАлгоритмПоиска = Не ПустаяСтрока(АлгоритмПоиска);
	
	Пока НомерВариантаПоиска <= 10
		И ЕстьАлгоритмПоиска Цикл
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_ПКО_ПоследовательностьПолейПоиска(НомерВариантаПоиска, СвойстваПоиска, ПараметрыОбъекта, ПрекратитьПоиск,
																	  СсылкаНаОбъект, УстанавливатьУОбъектаВсеСвойстваПоиска, СтрокаИменСвойствПоиска,
																	  ПКО.ИмяОбработчикаПоследовательностьПолейПоиска);
				
			Иначе
				
				Выполнить(АлгоритмПоиска);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(73, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), "", "", 
				ТипОбъекта, Неопределено, НСтр("ru = 'Последовательность полей поиска'"));
			
		КонецПопытки;
		
		НеНужноВыполнятьПоиск = ПрекратитьПоиск = Истина 
			ИЛИ СтрокаИменСвойствПоиска = ПредыдущаяСтрокаПоиска
			ИЛИ ЗначениеЗаполнено(СсылкаНаОбъект);				
			
		Если НЕ НеНужноВыполнятьПоиск Тогда
	
			// сам поиск непосредственно
			СсылкаНаОбъект = НайтиЭлементПоСвойствамПоиска(ТипОбъекта, ИмяТипаОбъекта, СвойстваПоиска, СтруктураСвойств, 
				СтрокаИменСвойствПоиска, ПоискПоДатеНаРавенство);
				
			НеНужноВыполнятьПоиск = ЗначениеЗаполнено(СсылкаНаОбъект);
			
			Если СсылкаНаОбъект <> Неопределено
				И СсылкаНаОбъект.Пустая() Тогда
				СсылкаНаОбъект = Неопределено;
			КонецЕсли;
			
		КонецЕсли;
		
		Если НеНужноВыполнятьПоиск Тогда
		
			Если РежимПоискаОсновногоОбъекта Тогда
			
				ОбработатьУстановкуСвойствПоискаУОбъекта(УстанавливатьУОбъектаВсеСвойстваПоиска, 
													ТипОбъекта, 
													СвойстваПоиска, 
													СвойстваПоискаНеЗамещать, 
													СсылкаНаОбъект, 
													СозданныйОбъект, 
													НЕ РежимПоискаОсновногоОбъекта, 
													НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике, 
													ОбъектБылСозданВТекущейИнформационнойБазе);
					
			КонецЕсли;
						
			Прервать;
			
		КонецЕсли;	
	
		НомерВариантаПоиска = НомерВариантаПоиска + 1;
		ПредыдущаяСтрокаПоиска = СтрокаИменСвойствПоиска;
		
	КонецЦикла;
		
	Если Не ЕстьАлгоритмПоиска Тогда
		
		// 5. Поиск объекта по полям поиска.
		СсылкаНаОбъект = НайтиЭлементПоСвойствамПоиска(ТипОбъекта, ИмяТипаОбъекта, СвойстваПоиска, СтруктураСвойств, 
					СтрокаИменСвойствПоиска, ПоискПоДатеНаРавенство);
		
	КонецЕсли;
	
	Если РежимПоискаОсновногоОбъекта
		И ЗначениеЗаполнено(СсылкаНаОбъект)
		И (ИмяТипаОбъекта = "Документ" 
		ИЛИ ИмяТипаОбъекта = "Задача"
		ИЛИ ИмяТипаОбъекта = "БизнесПроцесс") Тогда
		
		// Если у документа дата есть в свойствах поиска - то устанавливаем ее.
		ДатаПустая = Не ЗначениеЗаполнено(СвойстваПоиска["Дата"]);
		МожноЗамещать = (Не ДатаПустая) 
			И (СвойстваПоискаНеЗамещать["Дата"] = Неопределено);
			
		Если МожноЗамещать Тогда
			
			Если СозданныйОбъект = Неопределено Тогда
				СозданныйОбъект = СсылкаНаОбъект.ПолучитьОбъект();
			КонецЕсли;
			
			СозданныйОбъект.Дата = СвойстваПоиска["Дата"];
				
		КонецЕсли;
		
	КонецЕсли;		
	
	// Создавать новый объект нужно не всегда.
	Если (СсылкаНаОбъект = Неопределено
			ИЛИ СсылкаНаОбъект.Пустая())
		И СозданныйОбъект = Неопределено Тогда // Объект не найден по полям поиска.
		
		Если ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD Тогда
			
			СсылкаНаОбъект = СтруктураСвойств.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(СвойствоУникальныйИдентификатор));
			
		ИначеЕсли НЕ НеСоздаватьОбъектЕслиНеНайден Тогда
		
			СсылкаНаОбъект = СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, СозданныйОбъект, 
				НЕ РежимПоискаОсновногоОбъекта, ИзвестнаяСсылкаУникальногоИдентификатора, УстанавливатьУОбъектаВсеСвойстваПоиска);
				
		КонецЕсли;
			
		ОбъектНайден = Ложь;
		
	Иначе
		
		// Объект найден по полям поиска.
		ОбъектНайден = Истина;
			
	КонецЕсли;
	
	Если СсылкаНаОбъект <> Неопределено
		И СсылкаНаОбъект.Пустая() Тогда
		
		СсылкаНаОбъект = Неопределено;
		
	КонецЕсли;
	
	ОбъектНайденПоПолямПоиска = ОбъектНайден;
	
	Возврат СсылкаНаОбъект;
	
КонецФункции 

Процедура УстановитьСвойстваКоллекцииФайлаОбмена(Объект, КоллекцияФайлаОбмена, ИнформацияОТипах,
	ПараметрыОбъекта, НомерЗаписи, Знач ИмяТабличнойЧасти, Знач ИмяПоляСортировки)
	
	ИмяВетки = ИмяТабличнойЧасти + "ТабличнаяЧасть";
	
	СтрокаКоллекции = КоллекцияФайлаОбмена.Добавить();
	СтрокаКоллекции[ИмяПоляСортировки] = НомерЗаписи;
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Свойство" 
			ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда
			
			ЭтоПараметр = (ИмяУзла = "ЗначениеПараметра");
			
			Имя    = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
			ИмяПКО = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПКО");
			
			ТипСвойства = ТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя);
			
			ЗначениеСвойства = ПрочитатьСвойство(ТипСвойства,,, ИмяПКО);
			
			Если ЭтоПараметр Тогда
				
				ДобавитьСложныйПараметрПриНеобходимости(ПараметрыОбъекта, ИмяВетки, НомерЗаписи, Имя, ЗначениеСвойства);
				
			Иначе
				
				Попытка
					
					СтрокаКоллекции[Имя] = ЗначениеСвойства;
					
				Исключение
					
					ЗП = ЗаписьПротоколаОбмена(26, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
					ЗП.ИмяПКО           = ИмяПКО;
					ЗП.Объект           = Объект;
					ЗП.ТипОбъекта       = ТипЗнч(Объект);
					ЗП.Свойство         = "Объект." + ИмяТабличнойЧасти + "." + Имя;
					ЗП.Значение         = ЗначениеСвойства;
					ЗП.ТипЗначения      = ТипЗнч(ЗначениеСвойства);
					СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(26, ЗП, Истина);
					
					Если Не ПродолжитьПриОшибке Тогда
						ВызватьИсключение СтрокаСообщенияОбОшибке;
					КонецЕсли;
					
				КонецПопытки;
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "СубконтоДт" ИЛИ ИмяУзла = "СубконтоКт" Тогда
			
			одПропустить(ФайлОбмена);
				
		ИначеЕсли (ИмяУзла = "Запись") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Загружает табличную часть объекта.
//
Процедура ЗагрузитьТабличнуюЧасть(Объект, ИмяТабличнойЧасти, ОбщаяИнформацияОТипеДокумента, ПараметрыОбъекта, ПКО)
	
	Перем КлючевыеПоляПоиска;
	Перем МассивКлючевыхПолейПоиска;
	
	Результат = КлючевыеПоляПоискаПоТабличнойЧасти(ПКО, ИмяТабличнойЧасти, МассивКлючевыхПолейПоиска, КлючевыеПоляПоиска);
	
	Если Не Результат Тогда
		
		МассивКлючевыхПолейПоиска = Новый Массив;
		
		ОбъектМетаданныхТабличнаяЧасть = Объект.Метаданные().ТабличныеЧасти[ИмяТабличнойЧасти]; // ОбъектМетаданныхТабличнаяЧасть
		
		Для Каждого Реквизит Из ОбъектМетаданныхТабличнаяЧасть.Реквизиты Цикл
			
			МассивКлючевыхПолейПоиска.Добавить(Реквизит.Имя);
			
		КонецЦикла;
		
		КлючевыеПоляПоиска = СтрСоединить(МассивКлючевыхПолейПоиска, ",");
		
	КонецЕсли;
	
	УникальныйИдентификатор = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "_");
	
	ИмяПоляСортировки = "ПолеСортировки_[УникальныйИдентификатор]";
	ИмяПоляСортировки = СтрЗаменить(ИмяПоляСортировки, "[УникальныйИдентификатор]", УникальныйИдентификатор);
	
	ИмяКолонкиИтератора = "ПолеИтератора_[УникальныйИдентификатор]";
	ИмяКолонкиИтератора = СтрЗаменить(ИмяКолонкиИтератора, "[УникальныйИдентификатор]", УникальныйИдентификатор);
	
	ТабличнаяЧастьОбъекта = Объект[ИмяТабличнойЧасти];
	
	КоллекцияОбъекта = ТабличнаяЧастьОбъекта.Выгрузить(); // ТаблицаЗначений
	
	КоллекцияФайлаОбмена = КоллекцияОбъекта.СкопироватьКолонки();
	КоллекцияФайлаОбмена.Колонки.Добавить(ИмяПоляСортировки);
	
	ЗаполнитьКоллекциюФайлаОбмена(Объект, КоллекцияФайлаОбмена, ИмяТабличнойЧасти, ОбщаяИнформацияОТипеДокумента, ПараметрыОбъекта, МассивКлючевыхПолейПоиска, ИмяПоляСортировки);
	
	ДобавитьКолонкуСоЗначениемВТаблицу(КоллекцияФайлаОбмена, +1, ИмяКолонкиИтератора);
	ДобавитьКолонкуСоЗначениемВТаблицу(КоллекцияОбъекта,     -1, ИмяКолонкиИтератора);
	
	КоллекцияГруппировки = ИнициализацияТаблицыПоКлючевымПолям(МассивКлючевыхПолейПоиска);
	КоллекцияГруппировки.Колонки.Добавить(ИмяКолонкиИтератора);
	
	ЗаполнитьЗначенияСвойствТаблицы(КоллекцияФайлаОбмена, КоллекцияГруппировки);
	ЗаполнитьЗначенияСвойствТаблицы(КоллекцияОбъекта,     КоллекцияГруппировки);
	
	КоллекцияГруппировки.Свернуть(КлючевыеПоляПоиска, ИмяКолонкиИтератора);
	
	КоллекцияСортировки = ТабличнаяЧастьОбъекта.ВыгрузитьКолонки(); // ТаблицаЗначений
	КоллекцияСортировки.Колонки.Добавить(ИмяПоляСортировки);
	
	Для Каждого СтрокаКоллекции Из КоллекцияГруппировки Цикл
		
		// получаем структуру отбора
		Отбор = Новый Структура();
		
		Для Каждого ИмяПоля Из МассивКлючевыхПолейПоиска Цикл
			
			Отбор.Вставить(ИмяПоля, СтрокаКоллекции[ИмяПоля]);
			
		КонецЦикла;
		
		ЗначенияПолейСортировки = Неопределено;
		
		Если СтрокаКоллекции[ИмяКолонкиИтератора] = 0 Тогда
			
			// Заполняем строки табличной части из старой версии объекта.
			СтрокиКоллекцииОбъекта = КоллекцияОбъекта.НайтиСтроки(Отбор);
			
			ЗначенияПолейСортировки = КоллекцияФайлаОбмена.НайтиСтроки(Отбор);
			
		Иначе
			
			// Заполняем строки табличной части из коллекции файла обмена.
			СтрокиКоллекцииОбъекта = КоллекцияФайлаОбмена.НайтиСтроки(Отбор);
			
		КонецЕсли;
		
		// Добавляем строки табличной части объекта.
		Для Каждого СтрокаКоллекции Из СтрокиКоллекцииОбъекта Цикл
			
			СтрокаКоллекцииСортировки = КоллекцияСортировки.Добавить();
			
			ЗаполнитьЗначенияСвойств(СтрокаКоллекцииСортировки, СтрокаКоллекции);
			
			Если ЗначенияПолейСортировки <> Неопределено Тогда
				
				СтрокаКоллекцииСортировки[ИмяПоляСортировки] = ЗначенияПолейСортировки[СтрокиКоллекцииОбъекта.Найти(СтрокаКоллекции)][ИмяПоляСортировки];
				
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЦикла;
	
	КоллекцияСортировки.Сортировать(ИмяПоляСортировки);
	
	// Загружаем результат в табличную часть объекта.
	Попытка
		ТабличнаяЧастьОбъекта.Загрузить(КоллекцияСортировки);
	Исключение
		
		Текст = НСтр("ru = 'Имя табличной части: %1'");
		
		ЗП = ЗаписьПротоколаОбмена(83, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ЗП.Объект     = Объект;
		ЗП.ТипОбъекта = ТипЗнч(Объект);
		ЗП.Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Текст, ИмяТабличнойЧасти);
		ЗаписатьВПротоколВыполнения(83, ЗП);
		
		одПропустить(ФайлОбмена);
		Возврат;
	КонецПопытки;
	
КонецПроцедуры

Процедура ЗаполнитьЗначенияСвойствТаблицы(КоллекцияИсточник, КоллекцияПриемник)
	
	Для Каждого ЭлементКоллекции Из КоллекцияИсточник Цикл
		
		ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), ЭлементКоллекции);
		
	КонецЦикла;
	
КонецПроцедуры

Функция ИнициализацияТаблицыПоКлючевымПолям(МассивКлючевыхПолейПоиска)
	
	Коллекция = Новый ТаблицаЗначений;
	
	Для Каждого ИмяПоля Из МассивКлючевыхПолейПоиска Цикл
		
		Коллекция.Колонки.Добавить(ИмяПоля);
		
	КонецЦикла;
	
	Возврат Коллекция;
	
КонецФункции

Процедура ДобавитьКолонкуСоЗначениемВТаблицу(Коллекция, Значение, ИмяКолонкиИтератора)
	
	Коллекция.Колонки.Добавить(ИмяКолонкиИтератора);
	Коллекция.ЗаполнитьЗначения(Значение, ИмяКолонкиИтератора);
	
КонецПроцедуры

Процедура ЗаполнитьКоллекциюФайлаОбмена(Объект, КоллекцияФайлаОбмена, ИмяТабличнойЧасти, ОбщаяИнформацияОТипеДокумента, ПараметрыОбъекта, МассивКлючевыхПолейПоиска, ИмяПоляСортировки)
	
	ИмяВетки = ИмяТабличнойЧасти + "ТабличнаяЧасть";
	
	Если ОбщаяИнформацияОТипеДокумента <> Неопределено Тогда
		ИнформацияОТипах = ОбщаяИнформацияОТипеДокумента[ИмяВетки];
	Иначе
		ИнформацияОТипах = Неопределено;
	КонецЕсли;
	
	НомерЗаписи = 0;
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
				
		Если ИмяУзла = "Запись" Тогда
			
			УстановитьСвойстваКоллекцииФайлаОбмена(Объект, КоллекцияФайлаОбмена, ИнформацияОТипах, ПараметрыОбъекта, НомерЗаписи, ИмяТабличнойЧасти, ИмяПоляСортировки);
			
			НомерЗаписи = НомерЗаписи + 1;
			
		ИначеЕсли (ИмяУзла = "ТабличнаяЧасть") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Функция КлючевыеПоляПоискаПоТабличнойЧасти(ПКО, ИмяТабличнойЧасти, МассивКлючевыхПолейПоиска, КлючевыеПоляПоиска)
	
	Если ПКО = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ДанныеПоискаПоТЧ = ПКО.ПоискПоТабличнымЧастям.Найти("ТабличнаяЧасть." + ИмяТабличнойЧасти, "ИмяЭлемента");
	
	Если ДанныеПоискаПоТЧ = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если Не ДанныеПоискаПоТЧ.Валидное Тогда
		Возврат Ложь;
	КонецЕсли;
	
	МассивКлючевыхПолейПоиска = ДанныеПоискаПоТЧ.МассивКлючевыхПолейПоиска;
	КлючевыеПоляПоиска        = ДанныеПоискаПоТЧ.КлючевыеПоляПоиска;
	
	Возврат Истина;

КонецФункции

// Загружает движения объекта
//
// Параметры:
//  Объект         - объект, движения которого загружаем.
//  Имя            - имя регистра.
//  Очистить       - если Истина, то движения предварительно очищается.
// 
Процедура ЗагрузитьДвижения(Объект, Имя, Очистить, ОбщаяИнформацияОТипеДокумента, 
	ПараметрыОбъекта, Правило)
	
	ИмяДвижений = Имя + "НаборЗаписей";
	Если ОбщаяИнформацияОТипеДокумента <> Неопределено Тогда
		ИнформацияОТипах = ОбщаяИнформацияОТипеДокумента[ИмяДвижений];
	Иначе
	    ИнформацияОТипах = Неопределено;
	КонецЕсли;
	
	ДанныеПоискаПоТЧ = Неопределено;
	
	КопияТЧДляПоиска = Неопределено;
	
	Движения = Объект.Движения[Имя];
	
	Движения.Прочитать();
	Движения.Записывать = Истина;

	Если Очистить
		И Движения.Количество() <> 0 Тогда
		
		Если ДанныеПоискаПоТЧ <> Неопределено Тогда 
			КопияТЧДляПоиска = Движения.Выгрузить();
		КонецЕсли;
		
        Движения.Очистить();
		
	ИначеЕсли ДанныеПоискаПоТЧ <> Неопределено Тогда
		
		КопияТЧДляПоиска = Движения.Выгрузить();	
		
	КонецЕсли;
	
	НомерЗаписи = 0;
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
			
		Если      ИмяУзла = "Запись" Тогда
			
			Запись = Движения.Добавить();
			УстановитьСвойстваЗаписи(Запись, ИнформацияОТипах, ПараметрыОбъекта, ИмяДвижений, НомерЗаписи, ДанныеПоискаПоТЧ, КопияТЧДляПоиска);
			
			НомерЗаписи = НомерЗаписи + 1;
			
		ИначеЕсли (ИмяУзла = "НаборЗаписей") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Устанавливает свойства объекта (записи).
//
// Параметры:
//  Запись         - объект, свойства которого устанавливаем.
//                   Например, строка табличной части или запись регистра.
//
Процедура УстановитьСвойстваЗаписи(Запись, ИнформацияОТипах, 
	ПараметрыОбъекта, ИмяВетки, НомерЗаписи,
	ДанныеПоискаПоТЧ = Неопределено, КопияТЧДляПоиска = Неопределено)
	
	НужноОрганизоватьПоискПоТЧ = (ДанныеПоискаПоТЧ <> Неопределено)
								И (КопияТЧДляПоиска <> Неопределено)
								И КопияТЧДляПоиска.Количество() <> 0;
								
	Если НужноОрганизоватьПоискПоТЧ Тогда
									
		СтруктураЧтенияСвойств = Новый Структура();
		СтруктураЧтенияСубконто = Новый Структура();
		
	КонецЕсли;
		
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
				
		Если ИмяУзла = "Свойство"
			ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда
			
			
			ЭтоПараметр = (ИмяУзла = "ЗначениеПараметра");
			
			Имя    = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
			ИмяПКО = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПКО");
			
			Если Имя = "ВидДвижения" И СтрНайти(Метаданные.НайтиПоТипу(ТипЗнч(Запись)).ПолноеИмя(), "РегистрНакопления") Тогда
				
				ТипСвойства = ТипВидДвиженияНакопления;
				
			Иначе
				
				ТипСвойства = ТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя);
				
			КонецЕсли;
			
			ЗначениеСвойства = ПрочитатьСвойство(ТипСвойства,,, ИмяПКО);
			
			Если ЭтоПараметр Тогда
				ДобавитьСложныйПараметрПриНеобходимости(ПараметрыОбъекта, ИмяВетки, НомерЗаписи, Имя, ЗначениеСвойства);			
			ИначеЕсли НужноОрганизоватьПоискПоТЧ Тогда 
				СтруктураЧтенияСвойств.Вставить(Имя, ЗначениеСвойства);	
			Иначе
				
				Попытка
					
					Запись[Имя] = ЗначениеСвойства;
					
				Исключение
					
					ЗП = ЗаписьПротоколаОбмена(26, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
					ЗП.ИмяПКО           = ИмяПКО;
					ЗП.Объект           = Запись;
					ЗП.ТипОбъекта       = ТипЗнч(Запись);
					ЗП.Свойство         = Имя;
					ЗП.Значение         = ЗначениеСвойства;
					ЗП.ТипЗначения      = ТипЗнч(ЗначениеСвойства);
					СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(26, ЗП, Истина);
					
					Если Не ПродолжитьПриОшибке Тогда
						ВызватьИсключение СтрокаСообщенияОбОшибке;
					КонецЕсли;
					
				КонецПопытки;
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "СубконтоДт" ИЛИ ИмяУзла = "СубконтоКт" Тогда
			
			// Поиск по субконто не реализован.
			
			Ключ = Неопределено;
			Значение = Неопределено;
			
			Пока ФайлОбмена.Прочитать() Цикл
				
				ИмяУзла = ФайлОбмена.ЛокальноеИмя;
								
				Если ИмяУзла = "Свойство" Тогда
					
					Имя    = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
					ИмяПКО = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПКО");
					
					ТипСвойства = ТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя);
										
					Если Имя = "Ключ" Тогда
						
						Ключ = ПрочитатьСвойство(ТипСвойства);
						
					ИначеЕсли Имя = "Значение" Тогда
						
						Значение = ПрочитатьСвойство(ТипСвойства,,, ИмяПКО);
						
					КонецЕсли;
					
				ИначеЕсли (ИмяУзла = "СубконтоДт" ИЛИ ИмяУзла = "СубконтоКт") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
					
					Прервать;
					
				Иначе
					
					ЗаписатьВПротоколВыполнения(9);
					Прервать;
					
				КонецЕсли;
				
			КонецЦикла;
			
			Если Ключ <> Неопределено 
				И Значение <> Неопределено Тогда
				
				Если НЕ НужноОрганизоватьПоискПоТЧ Тогда
				
					Запись[ИмяУзла][Ключ] = Значение;
					
				Иначе
					
					СоответствиеЗаписи = Неопределено;
					Если НЕ СтруктураЧтенияСубконто.Свойство(ИмяУзла, СоответствиеЗаписи) Тогда
						СоответствиеЗаписи = Новый Соответствие;
						СтруктураЧтенияСубконто.Вставить(ИмяУзла, СоответствиеЗаписи);
					КонецЕсли;
					
					СоответствиеЗаписи.Вставить(Ключ, Значение);
					
				КонецЕсли;
				
			КонецЕсли;
				
		ИначеЕсли (ИмяУзла = "Запись") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Если НужноОрганизоватьПоискПоТЧ Тогда
		
		СтруктураПоиска = Новый Структура();
		
		Для Каждого ЭлементПоиска Из  ДанныеПоискаПоТЧ.ПоляПоискаТЧ Цикл
			
			ЗначениеЭлемента = Неопределено;
			СтруктураЧтенияСвойств.Свойство(ЭлементПоиска, ЗначениеЭлемента);
			
			СтруктураПоиска.Вставить(ЭлементПоиска, ЗначениеЭлемента);		
			
		КонецЦикла;		
		
		МассивРезультатовПоиска = КопияТЧДляПоиска.НайтиСтроки(СтруктураПоиска);
		
		НайденаЗапись = МассивРезультатовПоиска.Количество() > 0;
		Если НайденаЗапись Тогда
			ЗаполнитьЗначенияСвойств(Запись, МассивРезультатовПоиска[0]);
		КонецЕсли;
		
		// Поверх заполнение свойствами и значением субконто.
		Для Каждого КлючИЗначение Из СтруктураЧтенияСвойств Цикл
			
			Запись[КлючИЗначение.Ключ] = КлючИЗначение.Значение;
			
		КонецЦикла;
		
		Для Каждого ЭлементИмя Из СтруктураЧтенияСубконто Цикл
			
			Для Каждого ЭлементКлюч Из ЭлементИмя.Значение Цикл
			
				Запись[ЭлементИмя.Ключ][ЭлементКлюч.Ключ] = ЭлементКлюч.Значение;
				
			КонецЦикла;
			
		КонецЦикла;
		
	КонецЕсли;
	
КонецПроцедуры

// Загружает объект типа ОписаниеТипов из указанного xml-источника.
//
// Параметры:
//  Источник         - xml-источник.
// 
Функция ЗагрузитьТипыОбъекта(Источник)
	
	// КвалификаторыДаты
	
	СоставДаты =  одАтрибут(Источник, ТипСтрока,  "СоставДаты");
	
	// КвалификаторыСтроки
	
	Длина           =  одАтрибут(Источник, ТипЧисло,  "Длина");
	ДлинаДопустимая =  одАтрибут(Источник, ТипСтрока, "ДопустимаяДлина");
	
	// КвалификаторыЧисла
	
	Разрядность             = одАтрибут(Источник, ТипЧисло,  "Разрядность");
	РазрядностьДробнойЧасти = одАтрибут(Источник, ТипЧисло,  "РазрядностьДробнойЧасти");
	ЗнакДопустимый          = одАтрибут(Источник, ТипСтрока, "ДопустимыйЗнак");
	
	// Читаем массив типов
	
	МассивТипов = Новый Массив;
	
	Пока Источник.Прочитать() Цикл
		ИмяУзла = Источник.ЛокальноеИмя;
		
		Если      ИмяУзла = "Тип" Тогда
			МассивТипов.Добавить(Тип(одЗначениеЭлемента(Источник, ТипСтрока)));
		ИначеЕсли (ИмяУзла = "Типы") И ( Источник.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Прервать;
		Иначе
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если МассивТипов.Количество() > 0 Тогда
		
		// КвалификаторыДаты
		
		Если СоставДаты = "Дата" Тогда
			КвалификаторыДаты   = Новый КвалификаторыДаты(ЧастиДаты.Дата);
		ИначеЕсли СоставДаты = "ДатаВремя" Тогда
			КвалификаторыДаты   = Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя);
		ИначеЕсли СоставДаты = "Время" Тогда
			КвалификаторыДаты   = Новый КвалификаторыДаты(ЧастиДаты.Время);
		Иначе
			КвалификаторыДаты   = Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя);
		КонецЕсли;
		
		// КвалификаторыЧисла
		
		Если Разрядность > 0 Тогда
			Если ЗнакДопустимый = "Неотрицательный" Тогда
				Знак = ДопустимыйЗнак.Неотрицательный;
			Иначе
				Знак = ДопустимыйЗнак.Любой;
			КонецЕсли; 
			КвалификаторыЧисла  = Новый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти, Знак);
		Иначе
			КвалификаторыЧисла  = Новый КвалификаторыЧисла();
		КонецЕсли;
		
		// КвалификаторыСтроки
		
		Если Длина > 0 Тогда
			Если ДлинаДопустимая = "Фиксированная" Тогда
				ДлинаДопустимая = ДопустимаяДлина.Фиксированная;
			Иначе
				ДлинаДопустимая = ДопустимаяДлина.Переменная;
			КонецЕсли;
			КвалификаторыСтроки = Новый КвалификаторыСтроки(Длина, ДлинаДопустимая);
		Иначе
			КвалификаторыСтроки = Новый КвалификаторыСтроки();
		КонецЕсли; 
		
		Возврат Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыДаты);
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Процедура ЗаписатьДокументВБезопасномРежиме(Документ, ТипОбъекта)
	
	Если Документ.Проведен Тогда
						
		Документ.Проведен = Ложь;
			
	КонецЕсли;		
								
	ЗаписатьОбъектВИБ(Документ, ТипОбъекта);	
	
КонецПроцедуры

Функция ОбъектПоСсылкеИДопИнформации(СозданныйОбъект, Ссылка)
	
	// Если объект создали, то работаем с ним, если нашли - получаем объект.
	Если СозданныйОбъект <> Неопределено Тогда
		
		Объект = СозданныйОбъект;
		
	ИначеЕсли Ссылка = Неопределено Тогда
		
		Объект = Неопределено;
		
	ИначеЕсли Ссылка.Пустая() Тогда
		
		Объект = Неопределено;
		
	Иначе
		
		Объект = Ссылка.ПолучитьОбъект();
		
	КонецЕсли;
	
	Возврат Объект;
КонецФункции

Процедура КомментарииКЗагрузкеОбъекта(НПП, ИмяПравила, Источник, ТипОбъекта, ГНПП = 0)
	
	Если ФлагКомментироватьОбработкуОбъектов Тогда
		
		СтрокаСообщения = НСтр("ru = 'Загрузка объекта № %1'");
		Номер = ?(НПП <> 0, НПП, ГНПП);
		СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, Номер);
		
		ЗП = ЗаписьПротоколаОбмена();
		
		Если Не ПустаяСтрока(ИмяПравила) Тогда
			
			ЗП.ИмяПКО = ИмяПравила;
			
		КонецЕсли;
		
		Если Не ПустаяСтрока(Источник) Тогда
			
			ЗП.Источник = Источник;
			
		КонецЕсли;
		
		ЗП.ТипОбъекта = ТипОбъекта;
		ЗаписатьВПротоколВыполнения(СтрокаСообщения, ЗП, Ложь);
		
	КонецЕсли;	
	
КонецПроцедуры

Процедура ДобавитьПараметрПриНеобходимости(ПараметрыДанных, ИмяПараметра, ЗначениеПараметра)
	
	Если ПараметрыДанных = Неопределено Тогда
		ПараметрыДанных = Новый Соответствие;
	КонецЕсли;
	
	ПараметрыДанных.Вставить(ИмяПараметра, ЗначениеПараметра);
	
КонецПроцедуры

Процедура ДобавитьСложныйПараметрПриНеобходимости(ПараметрыДанных, ИмяВеткиПараметров, НомерСтроки, ИмяПараметра, ЗначениеПараметра)
	
	Если ПараметрыДанных = Неопределено Тогда
		ПараметрыДанных = Новый Соответствие;
	КонецЕсли;
	
	ТекущиеДанныеПараметра = ПараметрыДанных[ИмяВеткиПараметров];
	
	Если ТекущиеДанныеПараметра = Неопределено Тогда
		
		ТекущиеДанныеПараметра = Новый ТаблицаЗначений;
		ТекущиеДанныеПараметра.Колонки.Добавить("НомерСтроки");
		ТекущиеДанныеПараметра.Колонки.Добавить("ИмяПараметра");
		ТекущиеДанныеПараметра.Индексы.Добавить("НомерСтроки");
		
		ПараметрыДанных.Вставить(ИмяВеткиПараметров, ТекущиеДанныеПараметра);	
		
	КонецЕсли;
	
	Если ТекущиеДанныеПараметра.Колонки.Найти(ИмяПараметра) = Неопределено Тогда
		ТекущиеДанныеПараметра.Колонки.Добавить(ИмяПараметра);
	КонецЕсли;		
	
	ДанныеСтроки = ТекущиеДанныеПараметра.Найти(НомерСтроки, "НомерСтроки");
	Если ДанныеСтроки = Неопределено Тогда
		ДанныеСтроки = ТекущиеДанныеПараметра.Добавить();
		ДанныеСтроки.НомерСтроки = НомерСтроки;
	КонецЕсли;		
	
	ДанныеСтроки[ИмяПараметра] = ЗначениеПараметра;
	
КонецПроцедуры

Функция ПрочитатьИнформациюОРегистрацииОбъекта()
	
	// Присваиваем ПЕРЕКРЕСТНЫЕ значения переменным; РС симметричен.
	УникальныйИдентификаторПриемника = одАтрибут(ФайлОбмена, ТипСтрока, "УникальныйИдентификаторИсточника");
	УникальныйИдентификаторИсточника = одАтрибут(ФайлОбмена, ТипСтрока, "УникальныйИдентификаторПриемника");
	ТипПриемника                     = одАтрибут(ФайлОбмена, ТипСтрока, "ТипИсточника");
	ТипИсточника                     = одАтрибут(ФайлОбмена, ТипСтрока, "ТипПриемника");
	ПустойНабор                      = одАтрибут(ФайлОбмена, ТипБулево, "ПустойНабор");
	
	Попытка
		УникальныйИдентификаторИсточника = Новый УникальныйИдентификатор(УникальныйИдентификаторИсточника);
	Исключение
		
		одПропустить(ФайлОбмена, "ИнформацияОРегистрацииОбъекта");
		Возврат Неопределено;
		
	КонецПопытки;
	
	// Получаем структуру свойств источника по типу источника.
	Попытка
		СтруктураСвойств = Менеджеры[Тип(ТипИсточника)];
	Исключение
		одПропустить(ФайлОбмена, "ИнформацияОРегистрацииОбъекта");
		Возврат Неопределено;
	КонецПопытки;
	
	// Получаем ссылку источника по GUID.
	УникальныйИдентификаторИсточника = СтруктураСвойств.Менеджер.ПолучитьСсылку(УникальныйИдентификаторИсточника);
	
	// Если ссылка не получена, то записывать такой набор не следует.
	Если Не ЗначениеЗаполнено(УникальныйИдентификаторИсточника) Тогда
		одПропустить(ФайлОбмена, "ИнформацияОРегистрацииОбъекта");
		Возврат Неопределено;
	КонецЕсли;
	
	НаборЗаписей = МенеджерРегистраСоответствийОбъектов.СоздатьНаборЗаписей(); // РегистрСведенийНаборЗаписей.СоответствияОбъектовИнформационныхБаз
	
	// отбор для набора записей
	НаборЗаписей.Отбор.УзелИнформационнойБазы.Установить(УзелОбменаЗагрузкаДанных);
	НаборЗаписей.Отбор.УникальныйИдентификаторИсточника.Установить(УникальныйИдентификаторИсточника);
	НаборЗаписей.Отбор.УникальныйИдентификаторПриемника.Установить(УникальныйИдентификаторПриемника);
	НаборЗаписей.Отбор.ТипИсточника.Установить(ТипИсточника);
	НаборЗаписей.Отбор.ТипПриемника.Установить(ТипПриемника);
	
	Если Не ПустойНабор Тогда
		
		// Добавляем одну запись в набор.
		СтрокаНабора = НаборЗаписей.Добавить();
		
		СтрокаНабора.УзелИнформационнойБазы           = УзелОбменаЗагрузкаДанных;
		СтрокаНабора.УникальныйИдентификаторИсточника = УникальныйИдентификаторИсточника;
		СтрокаНабора.УникальныйИдентификаторПриемника = УникальныйИдентификаторПриемника;
		СтрокаНабора.ТипИсточника                     = ТипИсточника;
		СтрокаНабора.ТипПриемника                     = ТипПриемника;
		
	КонецЕсли;
	
	// записываем набор записей
	ЗаписатьОбъектВИБ(НаборЗаписей, "РегистрСведенийНаборЗаписей.СоответствияОбъектовИнформационныхБаз");
	
	одПропустить(ФайлОбмена, "ИнформацияОРегистрацииОбъекта");
	
	Возврат НаборЗаписей;
	
КонецФункции

Процедура ВыгрузитьКорректировкуИнформацииСопоставления()
	
	ПравилаКонвертации = ТаблицаПравилКонвертации.Скопировать(Новый Структура("СинхронизироватьПоИдентификатору", Истина), "ТипИсточника, ТипПриемника");
	ПравилаКонвертации.Свернуть("ТипИсточника, ТипПриемника");
	
	Для Каждого Правило Из ПравилаКонвертации Цикл
		
		Менеджер = Менеджеры.Получить(Тип(Правило.ТипИсточника)).Менеджер; // СправочникМенеджер, ДокументМенеджер, и т.п.
		
		Если ТипЗнч(Менеджер) = Тип("ТочкиМаршрутаБизнесПроцесса") Тогда
			Продолжить;
		КонецЕсли;
		
		Если Менеджер <> Неопределено Тогда
			
			Выборка = Менеджер.Выбрать();
			
			Пока Выборка.Следующий() Цикл
				
				УникальныйИдентификатор = Строка(Выборка.Ссылка.УникальныйИдентификатор());
				
				Приемник = СоздатьУзел("КорректировкаИнформацииОРегистрацииОбъекта");
				
				УстановитьАтрибут(Приемник, "УникальныйИдентификатор", УникальныйИдентификатор);
				УстановитьАтрибут(Приемник, "ТипИсточника",            Правило.ТипИсточника);
				УстановитьАтрибут(Приемник, "ТипПриемника",            Правило.ТипПриемника);
				
				Приемник.ЗаписатьКонецЭлемента(); // КорректировкаИнформацииОРегистрацииОбъекта
				
				ЗаписатьВФайл(Приемник);
				
			КонецЦикла;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПрочитатьКорректировкуИнформацииСопоставления()
	
	// Присваиваем ПЕРЕКРЕСТНЫЕ значения переменным; РС симметричен.
	УникальныйИдентификатор = одАтрибут(ФайлОбмена, ТипСтрока, "УникальныйИдентификатор");
	ТипПриемника            = одАтрибут(ФайлОбмена, ТипСтрока, "ТипИсточника");
	ТипИсточника            = одАтрибут(ФайлОбмена, ТипСтрока, "ТипПриемника");
	
	УникальныйИдентификаторПриемника = УникальныйИдентификатор;
	УникальныйИдентификаторИсточника = УникальныйИдентификатор;
	
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("УзелИнформационнойБазы", УзелОбменаЗагрузкаДанных);
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("УникальныйИдентификаторПриемника", УникальныйИдентификаторПриемника);
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("ТипПриемника", ТипПриемника);
	ЗапросСоответствияОбъектовИнформационныхБаз.УстановитьПараметр("ТипИсточника", ТипИсточника);
	
	РезультатЗапроса = ЗапросСоответствияОбъектовИнформационныхБаз.Выполнить();
	
	Если Не РезультатЗапроса.Пустой() Тогда
		Возврат; // Информация в регистре уже имеется; пропускаем данные.
	КонецЕсли;
	
	Попытка
		УникальныйИдентификатор = УникальныйИдентификаторИсточника;
		УникальныйИдентификаторИсточника = Новый УникальныйИдентификатор(УникальныйИдентификаторИсточника);
	Исключение
		Возврат;
	КонецПопытки;
	
	// Получаем структуру свойств источника по типу источника.
	СтруктураСвойств = Менеджеры[Тип(ТипИсточника)];
	
	// Получаем ссылку источника по GUID.
	УникальныйИдентификаторИсточника = СтруктураСвойств.Менеджер.ПолучитьСсылку(УникальныйИдентификаторИсточника);
	
	Объект = УникальныйИдентификаторИсточника.ПолучитьОбъект();
	
	Если Объект = Неопределено Тогда
		Возврат; // Такого объекта в базе нет; пропускаем данные.
	КонецЕсли;
	
	// Добавляем запись в регистр сопоставления.
	СтруктураЗаписи = Новый Структура;
	СтруктураЗаписи.Вставить("УзелИнформационнойБазы", УзелОбменаЗагрузкаДанных);
	СтруктураЗаписи.Вставить("УникальныйИдентификаторИсточника", УникальныйИдентификаторИсточника);
	СтруктураЗаписи.Вставить("УникальныйИдентификаторПриемника", УникальныйИдентификаторПриемника);
	СтруктураЗаписи.Вставить("ТипПриемника",                     ТипПриемника);
	СтруктураЗаписи.Вставить("ТипИсточника",                     ТипИсточника);
	
	РегистрыСведений.СоответствияОбъектовИнформационныхБаз.ДобавитьЗапись(СтруктураЗаписи);
	
	УвеличитьСчетчикЗагруженныхОбъектов();
	
КонецПроцедуры

Функция ПрочитатьНаборЗаписейРегистра()
	
	// Переменные-заглушки для поддержки механизма отладки кода обработчиков событий.
	Перем Ссылка,ОбъектНайден, НеЗамещатьОбъект, РежимЗаписи, РежимПроведения, ГенерироватьНовыйНомерИлиКодЕслиНеУказан, ОбъектМодифицирован;
	
	НПП						= одАтрибут(ФайлОбмена, ТипЧисло,  "Нпп");
	ИмяПравила				= одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПравила");
	ТипОбъектаСтрокой       = одАтрибут(ФайлОбмена, ТипСтрока, "Тип");
	ПриоритетОбъектаОбмена  = ПриоритетОбъектаОбмена(ФайлОбмена);
	
	ЭтоПустойНабор			= одАтрибут(ФайлОбмена, ТипБулево, "ПустойНабор");
	Если Не ЗначениеЗаполнено(ЭтоПустойНабор) Тогда
		ЭтоПустойНабор = Ложь;
	КонецЕсли;
	
	ТипОбъекта 				= Тип(ТипОбъектаСтрокой);
	Источник 				= Неопределено;
	СвойстваПоиска 			= Неопределено;
	
	КомментарииКЗагрузкеОбъекта(НПП, ИмяПравила, Неопределено, ТипОбъекта);
	
	ИмяТипаСтрокиРегистра = СтрЗаменить(ТипОбъектаСтрокой, "РегистрСведенийНаборЗаписей.", "РегистрСведенийЗапись.");
	ИмяРегистра = СтрЗаменить(ТипОбъектаСтрокой, "РегистрСведенийНаборЗаписей.", "");
	
	ТипСтрокиНабораРегистра = Тип(ИмяТипаСтрокиРегистра);
	
	СтруктураСвойств = Менеджеры[ТипСтрокиНабораРегистра];
	ИмяТипаОбъекта   = СтруктураСвойств.ИмяТипа;
	
	ИнформацияОТипах = СоответствиеТиповДанныхДляЗагрузки()[ТипСтрокиНабораРегистра];
	
	Объект          = Неопределено;
		
	Если Не ПустаяСтрока(ИмяПравила) Тогда
		
		Правило = Правила[ИмяПравила];
		ЕстьОбработчикПередЗагрузкой = Правило.ЕстьОбработчикПередЗагрузкой;
		ЕстьОбработчикПриЗагрузке    = Правило.ЕстьОбработчикПриЗагрузке;
		ЕстьОбработчикПослеЗагрузки  = Правило.ЕстьОбработчикПослеЗагрузки;
		
	Иначе
		
		ЕстьОбработчикПередЗагрузкой = Ложь;
		ЕстьОбработчикПриЗагрузке    = Ложь;
		ЕстьОбработчикПослеЗагрузки  = Ложь;
		
	КонецЕсли;

    // Глобальный обработчик события ПередЗагрузкойОбъекта.
	
	Если ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПередЗагрузкойОбъекта(ФайлОбмена, Отказ, НПП, Источник, ИмяПравила, Правило,
																	  ГенерироватьНовыйНомерИлиКодЕслиНеУказан,ТипОбъектаСтрокой,
																	  ТипОбъекта, НеЗамещатьОбъект, РежимЗаписи, РежимПроведения);
				
			Иначе
				
				Выполнить(Конвертация.ПередЗагрузкойОбъекта);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(53, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ИмяПравила, Источник, 
			ТипОбъекта, Неопределено, НСтр("ru = 'ПередЗагрузкойОбъекта (глобальный)'"));
			
		КонецПопытки;
		
		Если Отказ Тогда	//	Отказ от загрузки объекта
			
			одПропустить(ФайлОбмена, "НаборЗаписейРегистра");
			Возврат Неопределено;
			
		КонецЕсли;
		
	КонецЕсли;
	
	
	// Обработчик события ПередЗагрузкойОбъекта.
	Если ЕстьОбработчикПередЗагрузкой Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_ПКО_ПередЗагрузкойОбъекта(ФайлОбмена, Отказ, НПП, Источник, ИмяПравила, Правило,
															  ГенерироватьНовыйНомерИлиКодЕслиНеУказан, ТипОбъектаСтрокой,
															  ТипОбъекта, НеЗамещатьОбъект, РежимЗаписи, РежимПроведения);
				
			Иначе
				
				Выполнить(Правило.ПередЗагрузкой);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(19, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ИмяПравила, Источник, ТипОбъекта, Неопределено, "ПередЗагрузкойОбъекта");
			
		КонецПопытки;
		
		Если Отказ Тогда // Отказ от загрузки объекта
			
			одПропустить(ФайлОбмена, "НаборЗаписейРегистра");
			Возврат Неопределено;
			
		КонецЕсли;
		
	КонецЕсли;
	
	РежимЧтенияОтбора = Ложь;
	РежимЧтенияЗаписей = Ложь;
	
	ОтборРегистра = Неопределено;
	ТекущаяСтрокаНабораЗаписей = Неопределено;
	ПараметрыОбъекта = Неопределено;
	ПараметрыНабораЗаписей = Неопределено;
	НомерЗаписи = -1;
	
	// Читаем что там в регистре записано.
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Отбор" Тогда
			
			Если ФайлОбмена.ТипУзла <> ТипУзлаXMLКонецЭлемента Тогда
					
				Объект = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей();
				ОтборРегистра = Объект.Отбор;
			
				РежимЧтенияОтбора = Истина;
					
			КонецЕсли;			
		
		ИначеЕсли ИмяУзла = "Свойство"
			ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда
			
			ЭтоПараметрДляОбъекта = (ИмяУзла = "ЗначениеПараметра");
			
			Имя                = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
			НеЗамещатьСвойство = одАтрибут(ФайлОбмена, ТипБулево, "НеЗамещать");
			ИмяПКО             = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПКО");
			
			// Читаем и устанавливаем значение свойства.
			ТипСвойства = ТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя);
			СвойствоНеНайденоПоСсылке = Ложь;
			
			// Создавать нужно всегда
			Значение = ПрочитатьСвойство(ТипСвойства, ЭтоПустойНабор, СвойствоНеНайденоПоСсылке, ИмяПКО);
			
			Если ЭтоПараметрДляОбъекта Тогда
				
				Если РежимЧтенияОтбора Тогда
					ДобавитьПараметрПриНеобходимости(ПараметрыНабораЗаписей, Имя, Значение);
				Иначе
					// Дополняем коллекцию параметров объекта.
					ДобавитьПараметрПриНеобходимости(ПараметрыОбъекта, Имя, Значение);
					ДобавитьСложныйПараметрПриНеобходимости(ПараметрыНабораЗаписей, "Строки", НомерЗаписи, Имя, Значение);
				КонецЕсли;
				
			Иначе
 				
				Попытка
					
					Если РежимЧтенияОтбора Тогда
						ОбменДаннымиСлужебный.УстановитьЗначениеЭлементаОтбора(ОтборРегистра, Имя, Значение);
					ИначеЕсли РежимЧтенияЗаписей Тогда
						ТекущаяСтрокаНабораЗаписей[Имя] = Значение;
					КонецЕсли;
					
				Исключение
					
					ЗП = ЗаписьПротоколаОбмена(26, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
					ЗП.ИмяПКО           = ИмяПравила;
					ЗП.Источник         = Источник;
					ЗП.Объект           = Объект;
					ЗП.ТипОбъекта       = ТипОбъекта;
					ЗП.Свойство         = Имя;
					ЗП.Значение         = Значение;
					ЗП.ТипЗначения      = ТипЗнч(Значение);
					СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(26, ЗП, Истина);
					
					Если Не ПродолжитьПриОшибке Тогда
						ВызватьИсключение СтрокаСообщенияОбОшибке;
					КонецЕсли;
					
				КонецПопытки;
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "СтрокиНабораЗаписей" Тогда
			
			Если ФайлОбмена.ТипУзла <> ТипУзлаXMLКонецЭлемента Тогда
				
				// Обработчик события ПриЗагрузкеОбъекта
				// срабатывает перед чтением первой записи в наборе.
				Если РежимЧтенияОтбора = Истина
					И ЕстьОбработчикПриЗагрузке Тогда
					
					Попытка
						
						Если ОтладкаОбработчиковЗагрузки Тогда
							
							ВыполнитьОбработчик_ПКО_ПриЗагрузкеОбъекта(ФайлОбмена, ОбъектНайден, Объект, НеЗамещатьОбъект, ОбъектМодифицирован, Правило);
							
						Иначе
							
							Выполнить(Правило.ПриЗагрузке);
							
						КонецЕсли;
						
					Исключение
						
						ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(20, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
							ИмяПравила, Источник, ТипОбъекта, Объект, "ПриЗагрузкеОбъекта");
						
					КонецПопытки;
					
				КонецЕсли;
				
				РежимЧтенияОтбора = Ложь;
				РежимЧтенияЗаписей = Истина;
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "Объект" Тогда
			
			Если ФайлОбмена.ТипУзла <> ТипУзлаXMLКонецЭлемента Тогда
			
				ТекущаяСтрокаНабораЗаписей = Объект.Добавить();	
			    НомерЗаписи = НомерЗаписи + 1;
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "НаборЗаписейРегистра" И ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента Тогда
			
			Прервать;
						
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	// после загрузки
	Отказ = Ложь;
	Если ЕстьОбработчикПослеЗагрузки Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_ПКО_ПослеЗагрузкиОбъекта(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта,
															 ОбъектМодифицирован, ИмяТипаОбъекта, ОбъектНайден, Правило);
				
			Иначе
				
				Выполнить(Правило.ПослеЗагрузки);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(21, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ИмяПравила, Источник, ТипОбъекта, Объект, "ПослеЗагрузкиОбъекта");
			
		КонецПопытки;
		
	КонецЕсли;
	
	Если Отказ Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Если Объект <> Неопределено Тогда
		
		ПолучениеЭлемента = ПолучениеЭлементаДанных.Авто;
		ОтправкаНазад = Ложь;
		
		Объект.ДополнительныеСвойства.Вставить("ОбменДанными", Новый Структура("АнализДанных", Не РежимЗагрузкиДанныхВИнформационнуюБазу()));
		
		Если ПриоритетОбъектаОбмена <> Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаВыше Тогда
			СтандартныеПодсистемыСервер.ПриПолученииДанныхОтПодчиненного(Объект, ПолучениеЭлемента, ОтправкаНазад, УзелОбменаЗагрузкаДанныхОбъект);
		Иначе
			СтандартныеПодсистемыСервер.ПриПолученииДанныхОтГлавного(Объект, ПолучениеЭлемента, ОтправкаНазад, УзелОбменаЗагрузкаДанныхОбъект);
		КонецЕсли;
		
		Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда
			Возврат Неопределено;
		КонецЕсли;
		
		ЗаписатьОбъектВИБ(Объект, ТипОбъекта);
		
	КонецЕсли;
	
	Возврат Объект;
	
КонецФункции

Процедура ДополнитьСтекНеЗаписанныхОбъектов(НомерДляСтека, Объект, ИзвестнаяСсылка, ТипОбъекта, ИмяТипа, АвтоматическиГенерироватьКод = Ложь, ПараметрыОбъекта = Неопределено)
	
	СтрокаСтека = ГлобальныйСтекНеЗаписанныхОбъектов[НомерДляСтека];
	Если СтрокаСтека <> Неопределено Тогда
		Возврат;
	КонецЕсли;
	СтруктураПараметров = Новый Структура();
	СтруктураПараметров.Вставить("Объект",Объект);
	СтруктураПараметров.Вставить("ИзвестнаяСсылка",ИзвестнаяСсылка);
	СтруктураПараметров.Вставить("ТипОбъекта", ТипОбъекта);
	СтруктураПараметров.Вставить("ИмяТипа", ИмяТипа);
	СтруктураПараметров.Вставить("АвтоматическиГенерироватьКод", АвтоматическиГенерироватьКод);
	СтруктураПараметров.Вставить("ПараметрыОбъекта", ПараметрыОбъекта);

	ГлобальныйСтекНеЗаписанныхОбъектов.Вставить(НомерДляСтека, СтруктураПараметров);
	
КонецПроцедуры

Процедура УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП)
	
	НомерДляСтека = ?(НПП = 0, ГНПП, НПП);
	ГлобальныйСтекНеЗаписанныхОбъектов.Удалить(НомерДляСтека);
	
КонецПроцедуры

Процедура ПровестиЗаписьНеЗаписанныхОбъектов()
	
	Для Каждого СтрокаДанных Из ГлобальныйСтекНеЗаписанныхОбъектов Цикл
		
		// отложенная запись объектов
		Объект = СтрокаДанных.Значение.Объект;
		
		Если СтрокаДанных.Значение.АвтоматическиГенерироватьКод = Истина Тогда
			
			ПровестиГенерациюКодаНомераПриНеобходимости(Истина, Объект,
				СтрокаДанных.Значение.ИмяТипа, Истина);
			
		КонецЕсли;
		
		ЗаписатьОбъектВИБ(Объект, СтрокаДанных.Значение.ТипОбъекта);
		
	КонецЦикла;
	
	ГлобальныйСтекНеЗаписанныхОбъектов.Очистить();
	
КонецПроцедуры

Процедура ПровестиГенерациюКодаНомераПриНеобходимости(ГенерироватьНовыйНомерИлиКодЕслиНеУказан, Объект, ИмяТипаОбъекта, 
	РежимОбменДанными)
	
	Если Не ГенерироватьНовыйНомерИлиКодЕслиНеУказан
		ИЛИ НЕ РежимОбменДанными Тогда
		
		// Если номер не нужно генерировать, или не в режиме обмена данными то ничего не нужно делать... платформа сама все
		// сгенерирует.
		Возврат;
	КонецЕсли;
	
	// По типу документа смотрим заполнен кол или номер.
	Если ИмяТипаОбъекта = "Документ"
		ИЛИ ИмяТипаОбъекта =  "БизнесПроцесс"
		ИЛИ ИмяТипаОбъекта = "Задача" Тогда
		
		Если НЕ ЗначениеЗаполнено(Объект.Номер) Тогда
			
			Объект.УстановитьНовыйНомер();
			
		КонецЕсли;
		
	ИначеЕсли ИмяТипаОбъекта = "Справочник"
		ИЛИ ИмяТипаОбъекта = "ПланВидовХарактеристик"
		ИЛИ ИмяТипаОбъекта = "ПланОбмена" Тогда
		
		Если НЕ ЗначениеЗаполнено(Объект.Код) Тогда
			
			Объект.УстановитьНовыйКод();
			
		КонецЕсли;	
		
	КонецЕсли;
	
КонецПроцедуры

Функция ПриоритетОбъектаОбмена(ФайлОбмена)
		
	СтрокаПриоритета = одАтрибут(ФайлОбмена, ТипСтрока, "ПриоритетОбъектаОбмена");
	Если ПустаяСтрока(СтрокаПриоритета) Тогда
		ЗначениеПриоритета = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаВыше;
	ИначеЕсли СтрокаПриоритета = "Выше" Тогда
		ЗначениеПриоритета = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаВыше;
	ИначеЕсли СтрокаПриоритета = "Ниже" Тогда
		ЗначениеПриоритета = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаНиже;
	ИначеЕсли СтрокаПриоритета = "Совпадает" Тогда
		ЗначениеПриоритета = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаСовпадает;
	КонецЕсли;
	
	Возврат ЗначениеПриоритета;
	
КонецФункции

// Читает очередной объект из файла обмена, производит загрузку.
//
// Параметры:
//  Нет.
// 
Функция ПрочитатьОбъект(УникальныйИдентификаторСтрокой = "")

	НПП						= одАтрибут(ФайлОбмена, ТипЧисло,  "Нпп");
	ГНПП					= одАтрибут(ФайлОбмена, ТипЧисло,  "ГНпп");
	Источник				= одАтрибут(ФайлОбмена, ТипСтрока, "Источник");
	ИмяПравила				= одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПравила");
	НеЗамещатьОбъект 		= одАтрибут(ФайлОбмена, ТипБулево, "НеЗамещать");
	ПрефиксАвтонумерации	= одАтрибут(ФайлОбмена, ТипСтрока, "ПрефиксАвтонумерации");
	ПриоритетОбъектаОбмена  = ПриоритетОбъектаОбмена(ФайлОбмена);
	
	ТипОбъектаСтрокой       = одАтрибут(ФайлОбмена, ТипСтрока, "Тип");
	ТипОбъекта 				= Тип(ТипОбъектаСтрокой);
	ИнформацияОТипах = СоответствиеТиповДанныхДляЗагрузки()[ТипОбъекта];
	
	КомментарииКЗагрузкеОбъекта(НПП, ИмяПравила, Источник, ТипОбъекта, ГНПП);
	
	СтруктураСвойств = Менеджеры[ТипОбъекта];
	ИмяТипаОбъекта   = СтруктураСвойств.ИмяТипа;
	
	// Временный обход: запоминаем в таблицу значений движения документов
	// по регистрам Бухгалтерии. После записи документа запишем движения.
	//
	ТаблицыОтложеннойЗаписиДвижений = Новый Соответствие;
	
	Если ИмяТипаОбъекта = "Документ" Тогда
		
		РежимЗаписи     = одАтрибут(ФайлОбмена, ТипСтрока, "РежимЗаписи");
		РежимПроведения = одАтрибут(ФайлОбмена, ТипСтрока, "РежимПроведения");
		
	КонецЕсли;
	
	Объект          = Неопределено; // СправочникОбъект, ДокументОбъект, РегистрСведенийНаборЗаписей, и т.п.
	ОбъектНайден    = Истина;
	ОбъектБылСозданВТекущейИнформационнойБазе = Неопределено;
	
	СвойстваПоиска  = Новый Соответствие;
	СвойстваПоискаНеЗамещать  = Новый Соответствие;
	
	Если Не ПустаяСтрока(ИмяПравила) Тогда
		
		Правило = Правила[ИмяПравила];
		ЕстьОбработчикПередЗагрузкой = Правило.ЕстьОбработчикПередЗагрузкой;
		ЕстьОбработчикПриЗагрузке    = Правило.ЕстьОбработчикПриЗагрузке;
		ЕстьОбработчикПослеЗагрузки  = Правило.ЕстьОбработчикПослеЗагрузки;
		ГенерироватьНовыйНомерИлиКодЕслиНеУказан = Правило.ГенерироватьНовыйНомерИлиКодЕслиНеУказан;
		НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике =  Правило.НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике;
		
	Иначе
		
		ЕстьОбработчикПередЗагрузкой = Ложь;
		ЕстьОбработчикПриЗагрузке    = Ложь;
		ЕстьОбработчикПослеЗагрузки  = Ложь;
		ГенерироватьНовыйНомерИлиКодЕслиНеУказан = Ложь;
		НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = Ложь;
		
	КонецЕсли;


	// Глобальный обработчик события ПередЗагрузкойОбъекта.
	
	Если ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПередЗагрузкойОбъекта(ФайлОбмена, Отказ, НПП, Источник, ИмяПравила, Правило,
																	  ГенерироватьНовыйНомерИлиКодЕслиНеУказан,ТипОбъектаСтрокой,
																	  ТипОбъекта, НеЗамещатьОбъект, РежимЗаписи, РежимПроведения);
				
			Иначе
				
				Выполнить(Конвертация.ПередЗагрузкойОбъекта);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(53, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ИмяПравила, Источник, ТипОбъекта, Неопределено, НСтр("ru = 'ПередЗагрузкойОбъекта (глобальный)'"));
				
		КонецПопытки;
				
		Если Отказ Тогда	//	Отказ от загрузки объекта
			
			одПропустить(ФайлОбмена, "Объект");
			Возврат Неопределено;
			
		КонецЕсли;
		
	КонецЕсли;
	
	
	// Обработчик события ПередЗагрузкойОбъекта.
	Если ЕстьОбработчикПередЗагрузкой Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_ПКО_ПередЗагрузкойОбъекта(ФайлОбмена, Отказ, НПП, Источник, ИмяПравила, Правило,
															  ГенерироватьНовыйНомерИлиКодЕслиНеУказан, ТипОбъектаСтрокой,
															  ТипОбъекта, НеЗамещатьОбъект, РежимЗаписи, РежимПроведения);
				
			Иначе
				
				Выполнить(Правило.ПередЗагрузкой);
				
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(19, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				ИмяПравила, Источник, ТипОбъекта, Неопределено, "ПередЗагрузкойОбъекта");
			
		КонецПопытки;
		
		Если Отказ Тогда // Отказ от загрузки объекта
			
			одПропустить(ФайлОбмена, "Объект");
			Возврат Неопределено;
			
		КонецЕсли;
		
	КонецЕсли;

	РежимРаботыСКонстантами = Ложь;
	ИмяКонстанты = "";
	
	НППГлобальнойСсылки = 0;
	НППСсылки = 0;
	ПараметрыОбъекта = Неопределено;
	НаборЗаписей = Неопределено;
	ЗаписатьОбъект = Истина;
	
	// Флаг определяет был ли объект найден по полям поиска в режиме сопоставления объектов или нет;
	// если флаг установлен, то в регистр сопоставления добавляется информация о сопоставлении GUID ссылки источника и
	// приемника.
	ОбъектНайденПоПолямПоиска = Ложь;
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
				
		Если ИмяУзла = "Свойство"
			ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда
			
			ЭтоПараметрДляОбъекта = (ИмяУзла = "ЗначениеПараметра");
			
			Если Объект = Неопределено Тогда
				
				// Объект не нашли и не создали - попробуем сейчас это сделать.
				ОбъектНайден = Ложь;
				
				// Обработчик события ПриЗагрузкеОбъекта.
				Если ЕстьОбработчикПриЗагрузке Тогда
					ОбъектМодифицирован = Истина;
					// Если есть обработчик при загрузке, то объект нужно перезаписывать, так как могут быть изменения.
					Попытка
						
						Если ОтладкаОбработчиковЗагрузки Тогда
							
							ВыполнитьОбработчик_ПКО_ПриЗагрузкеОбъекта(ФайлОбмена, ОбъектНайден, Объект, НеЗамещатьОбъект, ОбъектМодифицирован, Правило);
							
						Иначе
							
							Выполнить(Правило.ПриЗагрузке);
							
						КонецЕсли;
						
					Исключение
						
						ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(20, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
							ИмяПравила, Источник, ТипОбъекта, Объект, "ПриЗагрузкеОбъекта");
						
					КонецПопытки;
					
				КонецЕсли;
				
				// Так м не смогли создать объект в событии - создаем его отдельно.
				Если Объект = Неопределено Тогда
					
					Если ИмяТипаОбъекта = "Константы" Тогда
						
						Объект = Неопределено;
						РежимРаботыСКонстантами = Истина;
												
					Иначе
						
						СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, Объект, Ложь, , ,НаборЗаписей);
																	
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЕсли; 

			
			Имя                = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
			НеЗамещатьСвойство = одАтрибут(ФайлОбмена, ТипБулево, "НеЗамещать");
			ИмяПКО             = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПКО");
			
			Если РежимРаботыСКонстантами Тогда
				
				Объект = Константы[Имя].СоздатьМенеджерЗначения();	
				ИмяКонстанты = Имя;
				Имя = "Значение";
				
			ИначеЕсли НЕ ЭтоПараметрДляОбъекта
				И ((ОбъектНайден И НеЗамещатьСвойство) 
				ИЛИ (Имя = "ЭтоГруппа") 
				ИЛИ (Объект[Имя] = NULL)) Тогда
				
				// неизвестное свойство
				одПропустить(ФайлОбмена, ИмяУзла);
				Продолжить;
				
			КонецЕсли; 

			
			// Читаем и устанавливаем значение свойства.
			ТипСвойства = ТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя);
			Значение    = ПрочитатьСвойство(ТипСвойства,,, ИмяПКО);
			
			Если ЭтоПараметрДляОбъекта Тогда
				
				// Дополняем коллекцию параметров объекта.
				ДобавитьПараметрПриНеобходимости(ПараметрыОбъекта, Имя, Значение);
				
			Иначе
				
				Попытка
					
					Объект[Имя] = Значение;
					
				Исключение
					
					ЗП = ЗаписьПротоколаОбмена(26, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
					ЗП.ИмяПКО           = ИмяПравила;
					ЗП.НПП              = НПП;
					ЗП.ГНПП             = ГНПП;
					ЗП.Источник         = Источник;
					ЗП.Объект           = Объект;
					ЗП.ТипОбъекта       = ТипОбъекта;
					ЗП.Свойство         = Имя;
					ЗП.Значение         = Значение;
					ЗП.ТипЗначения      = ТипЗнч(Значение);
					СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(26, ЗП, Истина);
					
					Если Не ПродолжитьПриОшибке Тогда
						ВызватьИсключение СтрокаСообщенияОбОшибке;
					КонецЕсли;
					
				КонецПопытки;
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "Ссылка" Тогда
			
			// Ссылка на элемент - сначала получаем по ссылке объект, а потом устанавливаем свойства.
			СоответствияОбъектовИнформационныхБаз = Неопределено;
			СозданныйОбъект = Неопределено;
			НеСоздаватьОбъектЕслиНеНайден = Неопределено;
			ИзвестнаяСсылкаУникальногоИдентификатора = Неопределено;
			НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике = Ложь;
			РегистрироватьОбъектНаУзлеОтправителе = Ложь;
												
			Ссылка = НайтиОбъектПоСсылке(ТипОбъекта,
										СвойстваПоиска,
										СвойстваПоискаНеЗамещать,
										ОбъектНайден,
										СозданныйОбъект,
										НеСоздаватьОбъектЕслиНеНайден,
										Истина,
										НППГлобальнойСсылки,
										НППСсылки,
										ОбъектНайденПоПолямПоиска,
										ИзвестнаяСсылкаУникальногоИдентификатора,
										Истина,
										ПараметрыОбъекта,
										НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике,
										ОбъектБылСозданВТекущейИнформационнойБазе,
										РегистрироватьОбъектНаУзлеОтправителе,
										УникальныйИдентификаторСтрокой,
										ИмяПравила,
										СоответствияОбъектовИнформационныхБаз);
				
			Если ИмяТипаОбъекта = "Перечисление" Тогда
				
				Объект = Ссылка;
				
			Иначе
				
				Объект = ОбъектПоСсылкеИДопИнформации(СозданныйОбъект, Ссылка);
				
				Если Объект = Неопределено Тогда
					
					одПропустить(ФайлОбмена, "Объект");
					Прервать;
					
				КонецЕсли;
				
				Если ОбъектНайден И НеЗамещатьОбъект И (Не ЕстьОбработчикПриЗагрузке) Тогда
					
					одПропустить(ФайлОбмена, "Объект");
					Прервать;
					
				КонецЕсли;
				
				Если Ссылка = Неопределено Тогда
					
					НомерДляСтека = ?(НПП = 0, ГНПП, НПП);
					ДополнитьСтекНеЗаписанныхОбъектов(НомерДляСтека, СозданныйОбъект, ИзвестнаяСсылкаУникальногоИдентификатора, ТипОбъекта, 
						ИмяТипаОбъекта, Правило.ГенерироватьНовыйНомерИлиКодЕслиНеУказан, ПараметрыОбъекта);
					
				КонецЕсли;
				
			КонецЕсли;
			
			// Обработчик события ПриЗагрузкеОбъекта.
			Если ЕстьОбработчикПриЗагрузке Тогда
				
				Попытка
					
					Если ОтладкаОбработчиковЗагрузки Тогда
						
						ВыполнитьОбработчик_ПКО_ПриЗагрузкеОбъекта(ФайлОбмена, ОбъектНайден, Объект, НеЗамещатьОбъект, ОбъектМодифицирован, Правило);
						
					Иначе
						
						Выполнить(Правило.ПриЗагрузке);
						
					КонецЕсли;
					
				Исключение
					
					ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(20, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
						ИмяПравила, Источник, ТипОбъекта, Объект, "ПриЗагрузкеОбъекта");
					
				КонецПопытки;
				
				Если ОбъектНайден И НеЗамещатьОбъект Тогда
					
					одПропустить(ФайлОбмена, "Объект");
					Прервать;
					
				КонецЕсли;
				
			КонецЕсли;
			
			Если РегистрироватьОбъектНаУзлеОтправителе = Истина Тогда
				Объект.ДополнительныеСвойства.Вставить("РегистрироватьОбъектНаУзлеОтправителе");
			КонецЕсли;
			
			Объект.ДополнительныеСвойства.Вставить("СоответствияОбъектовИнформационныхБаз", СоответствияОбъектовИнформационныхБаз);
			
		ИначеЕсли ИмяУзла = "ТабличнаяЧасть"
			  ИЛИ ИмяУзла = "НаборЗаписей" Тогда
			//
			
			Если РежимЗагрузкиДанныхВТаблицуЗначений()
				И ИмяТипаОбъекта <> "ПланОбмена" Тогда
				одПропустить(ФайлОбмена, ИмяУзла);
				Продолжить;
			КонецЕсли;
			
			Если Объект = Неопределено Тогда
				
				ОбъектНайден = Ложь;
				
				// Обработчик события ПриЗагрузкеОбъекта.
				
				Если ЕстьОбработчикПриЗагрузке Тогда
					
					Попытка
						
						Если ОтладкаОбработчиковЗагрузки Тогда
							
							ВыполнитьОбработчик_ПКО_ПриЗагрузкеОбъекта(ФайлОбмена, ОбъектНайден, Объект, НеЗамещатьОбъект, ОбъектМодифицирован, Правило);
							
						Иначе
							
							Выполнить(Правило.ПриЗагрузке);
							
						КонецЕсли;
						
					Исключение
						
						ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(20, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
							ИмяПравила, Источник, ТипОбъекта, Объект, "ПриЗагрузкеОбъекта");
						
					КонецПопытки;
						
				КонецЕсли;
				 
			КонецЕсли;
			
			Имя                = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
			НеЗамещатьСвойство = одАтрибут(ФайлОбмена, ТипБулево, "НеЗамещать");
			НеОчищать          = одАтрибут(ФайлОбмена, ТипБулево, "НеОчищать");

			Если ОбъектНайден И НеЗамещатьСвойство Тогда
				
				одПропустить(ФайлОбмена, ИмяУзла);
				Продолжить;
				
			КонецЕсли;
			
			Если Объект = Неопределено Тогда
					
				СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, Объект, Ложь);
									
			КонецЕсли;
						
			Если ИмяУзла = "ТабличнаяЧасть" Тогда
				
				Если ЗагрузкаТабличнойЧастиПоддерживается(Объект, Имя) = Истина Тогда
					
					// Загрузка элементов из табличной части.
					ЗагрузитьТабличнуюЧасть(Объект, Имя, ИнформацияОТипах, ПараметрыОбъекта, Правило);
					
				КонецЕсли;
				
			ИначеЕсли ИмяУзла = "НаборЗаписей" Тогда
				
				// загрузка движений
				ЗагрузитьДвижения(Объект, Имя, Не НеОчищать, ИнформацияОТипах, ПараметрыОбъекта, Правило);
				
				// "Хозрасчетный","Международный"
				Если Метаданные.РегистрыБухгалтерии.Найти(Имя) <> Неопределено Тогда
				
					ЗагруженныеДвижения = Объект.Движения[Имя].Выгрузить();
					Если ЗагруженныеДвижения.Количество() > 0 Тогда
						
						// Обход ошибки платформы 30178033.
						// Порядок субконто в записи регистра бухгалтерии не соответствует порядку,
						// который указан в счете учета.
						УстранитьОшибкуНазначенияВидаСубконто(ЗагруженныеДвижения);
						
						ТаблицыОтложеннойЗаписиДвижений.Вставить(Имя, ЗагруженныеДвижения);
						Объект.Движения[Имя].Очистить();
						
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЕсли;
			
		ИначеЕсли (ИмяУзла = "Объект") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Отказ = Ложь;
			
			// Глобальный обработчик события ПослеЗагрузкиОбъекта.
			Если ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта Тогда
				
				ОбъектМодифицирован = Истина;
				
				Попытка
					
					Если ОтладкаОбработчиковЗагрузки Тогда
						
						ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиОбъекта(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта,
																			 ОбъектМодифицирован, ИмяТипаОбъекта, ОбъектНайден);
						
					Иначе
						
						Выполнить(Конвертация.ПослеЗагрузкиОбъекта);
						
					КонецЕсли;
					
				Исключение
					
					ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(54, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
						ИмяПравила, Источник, ТипОбъекта, Объект, НСтр("ru = 'ПослеЗагрузкиОбъекта (глобальный)'"));
					
				КонецПопытки;
				
			КонецЕсли;
			
			// Обработчик события ПослеЗагрузкиОбъекта.
			Если ЕстьОбработчикПослеЗагрузки Тогда
				
				Попытка
					
					Если ОтладкаОбработчиковЗагрузки Тогда
						
						ВыполнитьОбработчик_ПКО_ПослеЗагрузкиОбъекта(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта,
																	 ОбъектМодифицирован, ИмяТипаОбъекта, ОбъектНайден, Правило);
						
					Иначе
						
						Выполнить(Правило.ПослеЗагрузки);
						
					КонецЕсли;
					
				Исключение
					
					ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(21, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
						ИмяПравила, Источник, ТипОбъекта, Объект, "ПослеЗагрузкиОбъекта");
					
				КонецПопытки;
				
			КонецЕсли;
			
			ПолучениеЭлемента = ПолучениеЭлементаДанных.Авто;
			ОтправкаНазад = Ложь;
			
			ТекОбъект = Объект;
			Если ИмяТипаОбъекта = "РегистрСведений" Тогда
				ТекОбъект = НаборЗаписей;
			КонецЕсли;
			Если ТекОбъект <> Неопределено Тогда
				Если ИмяТипаОбъекта <> "Перечисление"
					И ИмяТипаОбъекта <> "Константы" Тогда
					ТекОбъект.ДополнительныеСвойства.Вставить("ОбменДанными", Новый Структура("АнализДанных", Не РежимЗагрузкиДанныхВИнформационнуюБазу()));
				КонецЕсли;
				
				Если ПриоритетОбъектаОбмена <> Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаВыше Тогда
					СтандартныеПодсистемыСервер.ПриПолученииДанныхОтПодчиненного(ТекОбъект, ПолучениеЭлемента, ОтправкаНазад, УзелОбменаЗагрузкаДанныхОбъект);
				Иначе
					СтандартныеПодсистемыСервер.ПриПолученииДанныхОтГлавного(ТекОбъект, ПолучениеЭлемента, ОтправкаНазад, УзелОбменаЗагрузкаДанныхОбъект);
				КонецЕсли;
			КонецЕсли;
			
			Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда
				Отказ = Истина;
			КонецЕсли;
			
			Если Отказ Тогда
				УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП);
				Возврат Неопределено;
			КонецЕсли;
			
			Если ИмяТипаОбъекта = "Документ" Тогда
				
				Если РежимЗаписи = "Проведение" Тогда
					
					РежимЗаписи = РежимЗаписиДокумента.Проведение;
					
				ИначеЕсли РежимЗаписи = "ОтменаПроведения" Тогда
					
					РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения; 
					
				ИначеЕсли РежимЗаписи = "Запись" Тогда
					
					РежимЗаписи = РежимЗаписиДокумента.Запись;	
					
				Иначе
					
					// Определим как записывать документ.
					Если Объект.Проведен Тогда
						
						РежимЗаписи = РежимЗаписиДокумента.Проведение;
						
					Иначе
						
						// А документ вообще может проводиться или нет.
						ДокументМожетПроводиться = (Объект.Метаданные().Проведение = РазрешитьПроведениеДокумента);
						
						Если ДокументМожетПроводиться Тогда
							РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения;
						Иначе
							РежимЗаписи = РежимЗаписиДокумента.Запись;
						КонецЕсли;
						
					КонецЕсли;
					
				КонецЕсли;
				
				РежимПроведения = ?(РежимПроведения = "Оперативный", РежимПроведенияДокумента.Оперативный, РежимПроведенияДокумента.Неоперативный);
				
				// Если хотим провести документ, помеченный на удаление, то пометку удаления снимаем ...
				Если Объект.ПометкаУдаления
					И (РежимЗаписи = РежимЗаписиДокумента.Проведение) Тогда
					
					Объект.ПометкаУдаления = Ложь;
					
				КонецЕсли;
				
				ПровестиГенерациюКодаНомераПриНеобходимости(ГенерироватьНовыйНомерИлиКодЕслиНеУказан, Объект, 
				ИмяТипаОбъекта, Истина);
				
				Если РежимЗагрузкиДанныхВИнформационнуюБазу() Тогда
					
					Попытка
						
						// Записываем документ, информацию о необходимости его провести или отменить проведение отдельно фиксируем.
						
						// Документы которые просто нужно записать - так и записываем.
						Если РежимЗаписи = РежимЗаписиДокумента.Запись Тогда
							
							// Отключаем механизм регистрации объектов при отмене проведения документа.
							// Механизм регистрации будет выполнен при отложенном проведении документов
							// (оптимизация производительности загрузки данных).
							Объект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
							
							// Установка ОбменДанными.Загрузка для движений документа.
							Для Каждого ТекДвижение Из Объект.Движения Цикл
								УстановитьОбменДаннымиЗагрузка(ТекДвижение,, ОтправкаНазад);
							КонецЦикла;
							
							ЗаписатьОбъектВИБ(Объект, ТипОбъекта, ЗаписатьОбъект, ОтправкаНазад);
							
							ЗаписатьРегистрыБухгалтерии(Объект.Ссылка, ТаблицыОтложеннойЗаписиДвижений);
							
							Если ЗаписатьОбъект
								И Объект <> Неопределено
								И Объект.Ссылка <> Неопределено Тогда
								
								ОбъектыДляОтложеннойЗаписи().Вставить(Объект.Ссылка, Объект.ДополнительныеСвойства);
								
							КонецЕсли;
							
						ИначеЕсли РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения Тогда
							
							ОтменитьПроведениеОбъектаВИБ(Объект, ТипОбъекта, ЗаписатьОбъект);
							
						ИначеЕсли РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
							
							// Отключаем механизм регистрации объектов при отмене проведения документа.
							// Механизм регистрации будет выполнен при отложенном проведении документов
							// (оптимизация производительности загрузки данных).
							Объект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
							
							ОтменитьПроведениеОбъектаВИБ(Объект, ТипОбъекта, ЗаписатьОбъект);
							
							// Если документ был успешно записан и создана ссылка,
							// то помещаем документ в очередь для проведения.
							Если ЗаписатьОбъект
								И Объект <> Неопределено
								И Объект.Ссылка <> Неопределено Тогда
								
								СтрокаТаблицы = ДокументыДляОтложенногоПроведения().Добавить();
								СтрокаТаблицы.ДокументСсылка = Объект.Ссылка;
								СтрокаТаблицы.ДатаДокумента  = Объект.Дата;
								
								ДополнительныеСвойстваДляОтложенногоПроведения().Вставить(Объект.Ссылка, Объект.ДополнительныеСвойства);
								
							КонецЕсли;
							
						КонецЕсли;
						
					Исключение
						
						СтрокаОписанияОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
						
						Если ЗаписатьОбъект Тогда
							// Не смогли выполнить необходимые действия для документа.
							ЗаписатьДокументВБезопасномРежиме(Объект, ТипОбъекта);
						КонецЕсли;
						
						ЗП                        = ЗаписьПротоколаОбмена(25, СтрокаОписанияОшибки);
						ЗП.ИмяПКО                 = ИмяПравила;
						
						Если Не ПустаяСтрока(Источник) Тогда
							
							ЗП.Источник           = Источник;
							
						КонецЕсли;
						
						ЗП.ТипОбъекта             = ТипОбъекта;
						ЗП.Объект                 = Строка(Объект);
						ЗаписатьВПротоколВыполнения(25, ЗП);
						
						СтрокаСообщения = НСтр("ru = 'Ошибка при записи документа: %1. Описание ошибки: %2'");
						СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, Строка(Объект), СтрокаОписанияОшибки);
						
						// Объект не смогли в нормальном режиме записать - надо об этом сообщить.
						ВызватьИсключение СтрокаСообщения;
						
					КонецПопытки;
					
					УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП);
					
				КонецЕсли;
				
			ИначеЕсли ИмяТипаОбъекта <> "Перечисление" Тогда
				
				Если ИмяТипаОбъекта = "РегистрСведений" Тогда
					
					Периодический = СтруктураСвойств.Периодический;
					
					Если Периодический Тогда
						
						Если Не ЗначениеЗаполнено(Объект.Период) Тогда
							УстановитьТекущуюДатуРеквизиту(Объект.Период);
						КонецЕсли;
						
					КонецЕсли;
					Если НаборЗаписей <> Неопределено Тогда
						// Нужно отбор установить у регистра.
						Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
							ЭлементОтбора.Установить(Объект[ЭлементОтбора.Имя]);
						КонецЦикла;
						Объект = НаборЗаписей;
					КонецЕсли;
				КонецЕсли;
				
				ПровестиГенерациюКодаНомераПриНеобходимости(ГенерироватьНовыйНомерИлиКодЕслиНеУказан, Объект,
				ИмяТипаОбъекта, Истина);
				
				Если РежимЗагрузкиДанныхВИнформационнуюБазу() Тогда
					
					// Отключаем механизм регистрации объектов при отмене проведения документа.
					// Механизм регистрации будет выполнен при отложенном проведении документов
					// (оптимизация производительности загрузки данных).
					Если ИмяТипаОбъекта <> "Константы" Тогда
						Объект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
					КонецЕсли;
					
					ЗаписатьОбъектВИБ(Объект, ТипОбъекта, ЗаписатьОбъект, ОтправкаНазад);
					
					Если НЕ (ИмяТипаОбъекта = "РегистрСведений"
						 ИЛИ ИмяТипаОбъекта = "Константы") Тогда
						// Если объект был успешно записан и создана ссылка,
						// то помещаем объект в очередь для записи.
						Если ЗаписатьОбъект
							И Объект <> Неопределено
							И Объект.Ссылка <> Неопределено Тогда
							
							ОбъектыДляОтложеннойЗаписи().Вставить(Объект.Ссылка, Объект.ДополнительныеСвойства);
							
						КонецЕсли;
						
						УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП);
						
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЕсли;
			
			ЭтоСсылочныйТипОбъекта = НЕ(ИмяТипаОбъекта = "РегистрСведений"
										ИЛИ ИмяТипаОбъекта = "Константы");
			
			Прервать;
			
		ИначеЕсли ИмяУзла = "НаборЗаписейПоследовательности" Тогда
			
			одПропустить(ФайлОбмена);
			
		ИначеЕсли ИмяУзла = "Типы" Тогда

			Если Объект = Неопределено Тогда
				
				ОбъектНайден = Ложь;
				Ссылка  = СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, Объект, Истина);
								
			КонецЕсли; 

			ОписаниеТиповОбъекта = ЗагрузитьТипыОбъекта(ФайлОбмена);

			Если ОписаниеТиповОбъекта <> Неопределено Тогда
				
				Объект.ТипЗначения = ОписаниеТиповОбъекта;
				
			КонецЕсли; 
			
		Иначе
			
			ЗаписатьВПротоколВыполнения(9);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Объект;

КонецФункции

Процедура ВыполнитьПереходНаНовыйОбмен()
	
	ИмяПланаОбмена = ИмяПланаОбмена();
		
	НастройкиСтарогоПланаОбмена = 
		ОбменДаннымиСервер.ЗначениеНастройкиПланаОбмена(ИмяПланаОбмена, "ИмяПланаОбменаДляПереходаНаНовыйОбмен");
	ИмяПланаОбменаДляПерехода = НастройкиСтарогоПланаОбмена.ИмяПланаОбменаДляПереходаНаНовыйОбмен;
	
	НастройкаСинхронизацииДанных = Неопределено;
	Если ЗначениеЗаполнено(УзелДляОбмена) Тогда
		НастройкаСинхронизацииДанных = УзелДляОбмена;
	ИначеЕсли ЗначениеЗаполнено(УзелОбменаЗагрузкаДанных) Тогда
		НастройкаСинхронизацииДанных = УзелОбменаЗагрузкаДанных;
	КонецЕсли;

	ПланыОбмена[ИмяПланаОбменаДляПерехода].ВыполнитьПереходНаНовыйОбмен(НастройкаСинхронизацииДанных);
	СтрокаСообщения = НСтр("ru = 'Выполнен автоматический переход на синхронизацию данных через формат EnterpriseData.'");
	ЗаписьЖурналаРегистрацииОбменДанными(СтрокаСообщения, УровеньЖурналаРегистрации.Информация);
	ПолеРезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
	ВызватьИсключение НСтр("ru = 'Синхронизация данных по старой настройке отменена.'");
КонецПроцедуры

Функция ЗагрузкаТабличнойЧастиПоддерживается(Объект, ИмяТабличнойЧасти)
	
	МетаданныеОбъекта = Объект.Метаданные();
	Если НЕ Метаданные.Справочники.Содержит(МетаданныеОбъекта)
		И НЕ Метаданные.ПланыВидовХарактеристик.Содержит(МетаданныеОбъекта) Тогда
		
		Возврат Истина;
		
	КонецЕсли;
	
	ДляЭлемента = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента;
	Если Объект.ЭтоГруппа
		И МетаданныеОбъекта.ТабличныеЧасти[ИмяТабличнойЧасти].Использование = ДляЭлемента Тогда
		
		Возврат Ложь;
		
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Процедура ЗаписатьРегистрыБухгалтерии(Регистратор, ТаблицыОтложеннойЗаписиДвижений)
	
	Если НЕ ЗначениеЗаполнено(Регистратор.Ссылка) Тогда
		
		Возврат;
		
	КонецЕсли;
	
	Для каждого ОписаниеТаблицыДвижений Из ТаблицыОтложеннойЗаписиДвижений Цикл
		
		ИмяРегистра = ОписаниеТаблицыДвижений.Ключ;
		ТаблицаДвижений = ОписаниеТаблицыДвижений.Значение;
		
		Если ТипЗнч(ТаблицаДвижений) <> Тип("ТаблицаЗначений")
			ИЛИ ТаблицаДвижений.Количество() < 1 Тогда
			
			Продолжить;
			
		КонецЕсли;
		
		НаборЗаписейРегистра = РегистрыБухгалтерии[ИмяРегистра].СоздатьНаборЗаписей();
		НаборЗаписейРегистра.Отбор.Регистратор.Установить(Регистратор, Истина);
		Для каждого СтрокаТаблицы Из ТаблицаДвижений Цикл
			
			ЗаписьНабора = НаборЗаписейРегистра.Добавить();
			ЗаполнитьЗначенияСвойств(ЗаписьНабора, СтрокаТаблицы);
			
			НомерСубконтоДт = 0;
			Для каждого ОписаниеВидаСубконтоДт Из ЗаписьНабора.СчетДт.ВидыСубконто Цикл
				
				НомерСубконтоДт = НомерСубконтоДт + 1;
				ЗаписьНабора.СубконтоДт[ОписаниеВидаСубконтоДт.ВидСубконто] = СтрокаТаблицы["СубконтоДт" + Строка(НомерСубконтоДт)];
				
			КонецЦикла;
			
			НомерСубконтоКт = 0;
			Для каждого ОписаниеВидаСубконтоКт Из ЗаписьНабора.СчетКт.ВидыСубконто Цикл
				
				НомерСубконтоКт = НомерСубконтоКт + 1;
				ЗаписьНабора.СубконтоКт[ОписаниеВидаСубконтоКт.ВидСубконто] = СтрокаТаблицы["СубконтоКт" + Строка(НомерСубконтоКт)];
				
			КонецЦикла;
			
		КонецЦикла;
		
		ОбновлениеИнформационнойБазы.ЗаписатьНаборЗаписей(НаборЗаписейРегистра, Истина, Ложь, Ложь);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПроверитьКоллекциюСубконто(СтрокаТаблицы, ЗначенияДоИсправления, Направление, ЕстьОшибка)
	
	КоллекцияВидовСубконто = СтрокаТаблицы["Счет" + Направление].ВидыСубконто;
	
	Для каждого ВидСубконтоИзКоллекции Из КоллекцияВидовСубконто Цикл
		
		ТипСубконто = Направление + Строка(ВидСубконтоИзКоллекции.НомерСтроки);
		
		ИмяСубконто = "Субконто" + ТипСубконто;
		ИмяВидыСубконто = "ВидСубконто" + ТипСубконто;
		
		ОписаниеСубконто = Новый Структура;
		ОписаниеСубконто.Вставить("ЕстьОшибка", Ложь);
		ОписаниеСубконто.Вставить("Субконто", СтрокаТаблицы[ИмяСубконто]);
		ОписаниеСубконто.Вставить("ВидСубконто", СтрокаТаблицы[ИмяВидыСубконто]);
		
		Если СтрокаТаблицы[ИмяВидыСубконто] <> ВидСубконтоИзКоллекции.ВидСубконто Тогда
			
			ОписаниеСубконто.ЕстьОшибка = Истина;
			
			СтрокаТаблицы[ИмяСубконто] = Неопределено;
			СтрокаТаблицы[ИмяВидыСубконто] = ВидСубконтоИзКоллекции.ВидСубконто;
			
			ЕстьОшибка = Истина;
			
		КонецЕсли;
		
		ЗначенияДоИсправления.Вставить(ТипСубконто, ОписаниеСубконто);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура УстранитьОшибкуНазначенияВидаСубконто(ЗагруженныеДвижения)
	
	Для каждого СтрокаТаблицы Из ЗагруженныеДвижения Цикл
		
		ЕстьОшибка = Ложь;
		
		ЗначенияДоИсправления = Новый Соответствие;
		
		ПроверитьКоллекциюСубконто(СтрокаТаблицы, ЗначенияДоИсправления, "Дт", ЕстьОшибка);
		ПроверитьКоллекциюСубконто(СтрокаТаблицы, ЗначенияДоИсправления, "Кт", ЕстьОшибка);
		
		Если ЕстьОшибка Тогда
			
			Для каждого ЭлементСоответствия Из ЗначенияДоИсправления Цикл
				
				ОписаниеСубконто = ЭлементСоответствия.Значение;
				Если НЕ ОписаниеСубконто.ЕстьОшибка Тогда
					
					Продолжить;
					
				КонецЕсли;
				
				ИмяВидаСубконтоИсправляемого = "ВидСубконто" + ЭлементСоответствия.Ключ;
				
				Для каждого АльтернативныйЭлемент Из ЗначенияДоИсправления Цикл
					
					АльтернативноеОписание = АльтернативныйЭлемент.Значение;
					Если НЕ АльтернативноеОписание.ЕстьОшибка 
						ИЛИ ЭлементСоответствия.Ключ = АльтернативныйЭлемент.Ключ Тогда
						
						Продолжить;
						
					КонецЕсли;
					
					ТипЗначенияСубконто = СтрокаТаблицы[ИмяВидаСубконтоИсправляемого].ТипЗначения;
					Если СтрокаТаблицы[ИмяВидаСубконтоИсправляемого] = АльтернативноеОписание.ВидСубконто
						И ТипЗначенияСубконто.СодержитТип(ТипЗнч(АльтернативноеОписание["Субконто"])) Тогда
						
						СтрокаТаблицы["Субконто" + ЭлементСоответствия.Ключ] = АльтернативноеОписание["Субконто"];
						Прервать;
						
					КонецЕсли;
					
				КонецЦикла;
			
			КонецЦикла;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область ПроцедурыВыгрузкиДанных

Функция НаборДвиженийДокумента(СсылкаНаДокумент, ВидИсточника, ИмяРегистра)
	
	Если ВидИсточника = "НаборДвиженийРегистраНакопления" Тогда
		
		НаборДвиженийДокумента = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей();
		
	ИначеЕсли ВидИсточника = "НаборДвиженийРегистраСведений" Тогда
		
		НаборДвиженийДокумента = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей();
		
	ИначеЕсли ВидИсточника = "НаборДвиженийРегистраБухгалтерии" Тогда
		
		НаборДвиженийДокумента = РегистрыБухгалтерии[ИмяРегистра].СоздатьНаборЗаписей();
		
	ИначеЕсли ВидИсточника = "НаборДвиженийРегистраРасчета" Тогда	
		
		НаборДвиженийДокумента = РегистрыРасчета[ИмяРегистра].СоздатьНаборЗаписей();
		
	Иначе
		
		Возврат Неопределено;
		
	КонецЕсли;
	
	ОбменДаннымиСлужебный.УстановитьЗначениеЭлементаОтбора(НаборДвиженийДокумента.Отбор, "Регистратор", СсылкаНаДокумент.Ссылка);
	НаборДвиженийДокумента.Прочитать();
	
	Возврат НаборДвиженийДокумента;
	
КонецФункции

// Формирует узлы свойств объекта приемника в соответствии с указанной коллекцией правил конвертации свойств.
//
// Параметры:
//  Источник		     - произвольный источник данных.
//  Приемник		     - xml-узел объекта приемника.
//  ВходящиеДанные	     - произвольные вспомогательные данные, передаваемые правилу
//                         для выполнения конвертации.
//  ИсходящиеДанные      - произвольные вспомогательные данные, передаваемые правилам
//                         конвертации объектов свойств.
//  ПКО				     - ссылка на правило конвертации объектов (родитель коллекции правил конвертации свойств).
//  ПКГС                 - ссылка на правило конвертации группы свойств.
//  УзелКоллекцииСвойств - xml-узел коллекции свойств.
// 
Процедура ВыгрузитьГруппуСвойств(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКГС, УзелКоллекцииСвойств, 
	ВыгрузитьТолькоСсылку, СписокВременныхФайлов = Неопределено, ВыгрузкаСтрокиНабораЗаписейРегистра = Ложь)

	
	КоллекцияОбъектов = Неопределено;
	НеЗамещать        = ПКГС.НеЗамещать;
	НеОчищать         = Ложь;
	ВыгружатьГруппуЧерезФайл = ПКГС.ВыгружатьГруппуЧерезФайл;
	
	// Обработчик ПередОбработкойВыгрузки

	Если ПКГС.ЕстьОбработчикПередОбработкойВыгрузки Тогда
		
		Отказ = Ложь;
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПКГС_ПередОбработкойВыгрузки(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО,
																 ПКГС, Отказ, КоллекцияОбъектов, НеЗамещать, УзелКоллекцииСвойств, НеОчищать);
				
			Иначе
				
				Выполнить(ПКГС.ПередОбработкойВыгрузки);
				
			КонецЕсли;
			
		Исключение
			
			ЗП = ЗаписьПротоколаОбмена(48, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			ЗП.ПКО                    = ПКО.Имя + "  (" + ПКО.Наименование + ")";
			ЗП.ПКГС                   = ПКГС.Имя + "  (" + ПКГС.Наименование + ")";
			
			ОписаниеТипов = Новый ОписаниеТипов("Строка");
			ИсточникСтрока= ОписаниеТипов.ПривестиЗначение(Источник);
			Если Не ПустаяСтрока(ИсточникСтрока) Тогда
				ЗП.Объект = ОписаниеТипов.ПривестиЗначение(Источник) + "  (" + ТипЗнч(Источник) + ")";
			Иначе
				ЗП.Объект = "(" + ТипЗнч(Источник) + ")";
			КонецЕсли;
			
			ЗП.Обработчик             = "ПередОбработкойВыгрузкиГруппыСвойств";
			СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(48, ЗП);
			
			Если Не ПродолжитьПриОшибке Тогда
				ВызватьИсключение СтрокаСообщенияОбОшибке;
			КонецЕсли;
			
		КонецПопытки;
							
		Если Отказ Тогда // Отказ от обработки группы свойств.
			
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;

	
    ВидПриемника = ПКГС.ВидПриемника;
	ВидИсточника = ПКГС.ВидИсточника;
	
	
    // Создание узла коллекции подчиненных объектов.
	СтруктураУзлаСвойств = Неопределено;
	УзелКоллекцииОбъектов = Неопределено;
	ИмяГоловногоУзла = "";
	
	Если ВидПриемника = "ТабличнаяЧасть" Тогда
		
		ИмяГоловногоУзла = "ТабличнаяЧасть";
		
		СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, ИСТИНА, ПКГС.Приемник, ИмяГоловногоУзла);
		
		Если НеЗамещать Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеЗамещать", "true");
						
		КонецЕсли;
		
		Если НеОчищать Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеОчищать", "true");
						
		КонецЕсли;
		
	ИначеЕсли ВидПриемника = "ПодчиненныйСправочник" Тогда
				
		
	ИначеЕсли ВидПриемника = "НаборЗаписейПоследовательности" Тогда
		
		ИмяГоловногоУзла = "НаборЗаписей";
		
		СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, ИСТИНА, ПКГС.Приемник, ИмяГоловногоУзла);
		
	ИначеЕсли СтрНайти(ВидПриемника, "НаборДвижений") > 0 Тогда
		
		ИмяГоловногоУзла = "НаборЗаписей";
		
		СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, ИСТИНА, ПКГС.Приемник, ИмяГоловногоУзла);
		
		Если НеЗамещать Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеЗамещать", "true");
						
		КонецЕсли;
		
		Если НеОчищать Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеОчищать", "true");
						
		КонецЕсли;
		
	Иначе  // это простая группировка
		
		ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКГС.ПравилаГруппы, 
			УзелКоллекцииСвойств, , , Истина, Ложь);
		
		Если ПКГС.ЕстьОбработчикПослеОбработкиВыгрузки Тогда
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКГС_ПослеОбработкиВыгрузки(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																	ПКО, ПКГС, Отказ, УзелКоллекцииСвойств, УзелКоллекцииОбъектов);
					
				Иначе
					
					Выполнить(ПКГС.ПослеОбработкиВыгрузки);
					
				КонецЕсли;
				
			Исключение
				
				ЗП = ЗаписьПротоколаОбмена(49, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
				ЗП.ПКО                    = ПКО.Имя + "  (" + ПКО.Наименование + ")";
				ЗП.ПКГС                   = ПКГС.Имя + "  (" + ПКГС.Наименование + ")";
				
				ОписаниеТипов = Новый ОписаниеТипов("Строка");
				ИсточникСтрока= ОписаниеТипов.ПривестиЗначение(Источник);
				Если Не ПустаяСтрока(ИсточникСтрока) Тогда
					ЗП.Объект = ОписаниеТипов.ПривестиЗначение(Источник) + "  (" + ТипЗнч(Источник) + ")";
				Иначе
					ЗП.Объект = "(" + ТипЗнч(Источник) + ")";
				КонецЕсли;
				
				ЗП.Обработчик             = "ПослеОбработкиВыгрузкиГруппыСвойств";
				СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(49, ЗП);
			
				Если Не ПродолжитьПриОшибке Тогда
					ВызватьИсключение СтрокаСообщенияОбОшибке;
				КонецЕсли;
				
			КонецПопытки;
			
		КонецЕсли;
		
		Возврат;
		
	КонецЕсли;
	
	// Получение коллекции подчиненных объектов.
	
	Если КоллекцияОбъектов <> Неопределено Тогда
		
		// Инициализировали коллекцию в обработчике ПередОбработкой.
		
	ИначеЕсли ПКГС.ПолучитьИзВходящихДанных Тогда
		
		Попытка
			
			КоллекцияОбъектов = ВходящиеДанные[ПКГС.Приемник];
			
			Если ТипЗнч(КоллекцияОбъектов) = Тип("РезультатЗапроса") Тогда
				
				КоллекцияОбъектов = КоллекцияОбъектов.Выгрузить();
				
			КонецЕсли;
			
		Исключение
			
			ЗП = ЗаписьПротоколаОбмена(66, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			ЗП.ПКО  = ПКО.Имя + "  (" + ПКО.Наименование + ")";
			ЗП.ПКГС = ПКГС.Имя + "  (" + ПКГС.Наименование + ")";
			
			Попытка
				ЗП.Объект = Строка(Источник) + "  (" + ТипЗнч(Источник) + ")";
			Исключение
				ЗП.Объект = "(" + ТипЗнч(Источник) + ")";
			КонецПопытки;
			
			СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(66, ЗП);
			
			Если Не ПродолжитьПриОшибке Тогда
				ВызватьИсключение СтрокаСообщенияОбОшибке;
			КонецЕсли;
			
			Возврат;
		КонецПопытки;
		
	ИначеЕсли ВидИсточника = "ТабличнаяЧасть" Тогда
		
		КоллекцияОбъектов = Источник[ПКГС.Источник];
		
		Если ТипЗнч(КоллекцияОбъектов) = Тип("РезультатЗапроса") Тогда
			
			КоллекцияОбъектов = КоллекцияОбъектов.Выгрузить();
			
		КонецЕсли;
		
	ИначеЕсли ВидИсточника = "ПодчиненныйСправочник" Тогда
		
	ИначеЕсли СтрНайти(ВидИсточника, "НаборДвижений") > 0 Тогда
		
		КоллекцияОбъектов = НаборДвиженийДокумента(Источник, ВидИсточника, ПКГС.Источник);
				
	ИначеЕсли ПустаяСтрока(ПКГС.Источник) Тогда
		
		КоллекцияОбъектов = Источник[ПКГС.Приемник];
		
		Если ТипЗнч(КоллекцияОбъектов) = Тип("РезультатЗапроса") Тогда
			
			КоллекцияОбъектов = КоллекцияОбъектов.Выгрузить();
			
		КонецЕсли;
		
	КонецЕсли;

	ВыгружатьГруппуЧерезФайл = ВыгружатьГруппуЧерезФайл ИЛИ (КоллекцияОбъектов.Количество() > 1000);
	ВыгружатьГруппуЧерезФайл = ВыгружатьГруппуЧерезФайл И НЕ ВыгрузкаСтрокиНабораЗаписейРегистра;
	ВыгружатьГруппуЧерезФайл = ВыгружатьГруппуЧерезФайл И НЕ ЭтоОбменЧерезВнешнееСоединение();
	
	Если ВыгружатьГруппуЧерезФайл Тогда
		
		ПКГС.НуженУзелXMLПриВыгрузке = Ложь;
		
		Если СписокВременныхФайлов = Неопределено Тогда
			СписокВременныхФайлов = Новый СписокЗначений();
		КонецЕсли;
		
		ИмяФайлаЗаписей = ПолучитьИмяВременногоФайла();
		// Удаление временных файлов происходит не по месту, с помощью УдалитьФайлы(ИмяФайлаЗаписей), а централизованно.
		СписокВременныхФайлов.Добавить(ИмяФайлаЗаписей);
		
		ВременныйФайЗаписей = Новый ЗаписьТекста;
		Попытка
			
			ВременныйФайЗаписей.Открыть(ИмяФайлаЗаписей, КодировкаТекста.UTF8);
			
		Исключение
			
			СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Ошибка при создании временного файла для выгрузки данных.
					|Имя файла ""%1"".
					|Описание ошибки:
					|%2'"),
				Строка(ИмяФайлаЗаписей),
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
				
			ЗаписатьВПротоколВыполнения(СтрокаСообщенияОбОшибке);
			
		КонецПопытки;
		
		ИнформацияДляЗаписиВФайл = УзелКоллекцииОбъектов.Закрыть();
		ВременныйФайЗаписей.ЗаписатьСтроку(ИнформацияДляЗаписиВФайл);
		
	КонецЕсли;
	
	Для каждого ОбъектКоллекции Из КоллекцияОбъектов Цикл
		
		// Обработчик ПередВыгрузкой
		Если ПКГС.ЕстьОбработчикПередВыгрузкой Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКГС_ПередВыгрузкойСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО,
																	ПКГС, Отказ, ОбъектКоллекции, УзелКоллекцииСвойств, УзелКоллекцииОбъектов);
					
				Иначе
					
					Выполнить(ПКГС.ПередВыгрузкой);
					
				КонецЕсли;
				
			Исключение
				
				СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(50);
				Если Не ПродолжитьПриОшибке Тогда
					ВызватьИсключение СтрокаСообщенияОбОшибке;
				КонецЕсли;
				
				Прервать;
				
			КонецПопытки;
			
			Если Отказ Тогда // Отказ от выгрузки подчиненного объекта.
				
				Продолжить;
				
			КонецЕсли;
			
		КонецЕсли;
		
		// Обработчик ПриВыгрузке
		
		Если ПКГС.НуженУзелXMLПриВыгрузке ИЛИ ВыгружатьГруппуЧерезФайл Тогда
			УзелОбъектаКоллекции = СоздатьУзел("Запись");
		Иначе
			УзелКоллекцииОбъектов.ЗаписатьНачалоЭлемента("Запись");
			УзелОбъектаКоллекции = УзелКоллекцииОбъектов;
		КонецЕсли;
		
		СтандартнаяОбработка	= Истина;
		
		Если ПКГС.ЕстьОбработчикПриВыгрузке Тогда
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКГС_ПриВыгрузкеСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО,
																 ПКГС, ОбъектКоллекции, УзелКоллекцииОбъектов, УзелОбъектаКоллекции,
																 УзелКоллекцииСвойств, СтандартнаяОбработка);
					
				Иначе
					
					Выполнить(ПКГС.ПриВыгрузке);
					
				КонецЕсли;
			
		Исключение
				
				СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(51);
				Если Не ПродолжитьПриОшибке Тогда
					ВызватьИсключение СтрокаСообщенияОбОшибке;
				КонецЕсли;
				
				Прервать;
				
			КонецПопытки;
			
		КонецЕсли;
		
		// Выгрузка свойств объекта коллекции.
		Если СтандартнаяОбработка Тогда
			
			Если ПКГС.ПравилаГруппы.Количество() > 0 Тогда
				
				ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКГС.ПравилаГруппы, 
					УзелОбъектаКоллекции, ОбъектКоллекции, , Истина, Ложь);
				
			КонецЕсли;
			
		КонецЕсли;
		
		// Обработчик ПослеВыгрузки
		Если ПКГС.ЕстьОбработчикПослеВыгрузки Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКГС_ПослеВыгрузкиСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																   ПКО, ПКГС, Отказ, ОбъектКоллекции, УзелКоллекцииОбъектов,
																   УзелКоллекцииСвойств, УзелОбъектаКоллекции);
					
				Иначе
					
					Выполнить(ПКГС.ПослеВыгрузки);
					
				КонецЕсли;
				
			Исключение
				
				СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(52);
				Если Не ПродолжитьПриОшибке Тогда
					ВызватьИсключение СтрокаСообщенияОбОшибке;
				КонецЕсли;
				
				Прервать;
				
			КонецПопытки;
			
		Если Отказ Тогда // Отказ от выгрузки подчиненного объекта.
			
			Продолжить;
			
		КонецЕсли;
			
		КонецЕсли;
		
		Если ПКГС.НуженУзелXMLПриВыгрузке Тогда
			ДобавитьПодчиненный(УзелКоллекцииОбъектов, УзелОбъектаКоллекции);
		КонецЕсли;
		
		// Заполняем файл объектами узла.
		Если ВыгружатьГруппуЧерезФайл Тогда
			
			УзелОбъектаКоллекции.ЗаписатьКонецЭлемента();
			ИнформацияДляЗаписиВФайл = УзелОбъектаКоллекции.Закрыть();
			ВременныйФайЗаписей.ЗаписатьСтроку(ИнформацияДляЗаписиВФайл);
			
		Иначе
			
			Если Не ПКГС.НуженУзелXMLПриВыгрузке Тогда
				
				УзелКоллекцииОбъектов.ЗаписатьКонецЭлемента();
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	
	// Обработчик ПослеОбработкиВыгрузки
	Если ПКГС.ЕстьОбработчикПослеОбработкиВыгрузки Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПКГС_ПослеОбработкиВыгрузки(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																ПКО, ПКГС, Отказ, УзелКоллекцииСвойств, УзелКоллекцииОбъектов);
				
			Иначе
				
				Выполнить(ПКГС.ПослеОбработкиВыгрузки);
				
			КонецЕсли;
			
		Исключение
			
			ЗП = ЗаписьПротоколаОбмена(49, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			ЗП.ПКО                    = ПКО.Имя + "  (" + ПКО.Наименование + ")";
			ЗП.ПКГС                   = ПКГС.Имя + "  (" + ПКГС.Наименование + ")";
			
			ОписаниеТипов = Новый ОписаниеТипов("Строка");
			ИсточникСтрока= ОписаниеТипов.ПривестиЗначение(Источник);
			Если Не ПустаяСтрока(ИсточникСтрока) Тогда
				ЗП.Объект = ОписаниеТипов.ПривестиЗначение(Источник) + "  (" + ТипЗнч(Источник) + ")";
			Иначе
				ЗП.Объект = "(" + ТипЗнч(Источник) + ")";
			КонецЕсли;
			
			ЗП.Обработчик             = "ПослеОбработкиВыгрузкиГруппыСвойств";
			СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(49, ЗП);
		
			Если Не ПродолжитьПриОшибке Тогда
				ВызватьИсключение СтрокаСообщенияОбОшибке;
			КонецЕсли;
			
		КонецПопытки;
		
		Если Отказ Тогда // Отказ от записи коллекции подчиненных объектов.
			
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Если ВыгружатьГруппуЧерезФайл Тогда
		ВременныйФайЗаписей.ЗаписатьСтроку("</" + ИмяГоловногоУзла + ">"); // закрыть узел
		ВременныйФайЗаписей.Закрыть(); // закрыть файл явно
	Иначе
		ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелКоллекцииОбъектов);
	КонецЕсли;
	
КонецПроцедуры

Процедура ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник, ВыборкаДанных = Неопределено)
	
	Если Значение <> Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ПКС.ПолучитьИзВходящихДанных Тогда
			
		ОбъектДляПолученияДанных = ВходящиеДанные;
		
		Если Не ПустаяСтрока(ПКС.Приемник) Тогда
		
			ИмяСвойства = ПКС.Приемник;
			
		Иначе
			
			ИмяСвойства = ПКС.ИмяПараметраДляПередачи;
			
		КонецЕсли;
		
		КодОшибки = ?(ОбъектКоллекции <> Неопределено, 67, 68);
	
	ИначеЕсли ОбъектКоллекции <> Неопределено Тогда
		
		ОбъектДляПолученияДанных = ОбъектКоллекции;
		
		Если Не ПустаяСтрока(ПКС.Источник) Тогда
			
			ИмяСвойства = ПКС.Источник;
			КодОшибки = 16;
						
		Иначе
			
			ИмяСвойства = ПКС.Приемник;
			КодОшибки = 17;
            							
		КонецЕсли;
		
	ИначеЕсли ВыборкаДанных <> Неопределено Тогда
		
		ОбъектДляПолученияДанных = ВыборкаДанных;	
		
		Если Не ПустаяСтрока(ПКС.Источник) Тогда
		
			ИмяСвойства = ПКС.Источник;
			КодОшибки = 13;
			
		Иначе
			
			Возврат;
			
		КонецЕсли;
						
	Иначе
		
		ОбъектДляПолученияДанных = Источник;
		
		Если Не ПустаяСтрока(ПКС.Источник) Тогда
		
			ИмяСвойства = ПКС.Источник;
			КодОшибки = 13;
		
		Иначе
			
			ИмяСвойства = ПКС.Приемник;
			КодОшибки = 14;
		
		КонецЕсли;
			
	КонецЕсли;
	
	
	Попытка
		
		Значение = ОбъектДляПолученияДанных[ИмяСвойства];
		
		// Для ОписанияТипов дополнительно сериализуем значением в JSON
		Если ПКС.ТипИсточника = "ОпределениеТипа" Тогда
			
			Значение = ОписаниеТиповВJSON(Значение);
			
		КонецЕсли
		
	Исключение
		
		Если КодОшибки <> 14 Тогда
			ЗаписатьИнформациюОбОшибкеОбработчикиПКС(КодОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), ПКО, ПКС, Источник, "");
		КонецЕсли;
		
	КонецПопытки;
			
КонецПроцедуры

Процедура ВыгрузитьТипСвойстваЭлемента(УзелСвойства, ТипСвойства)
	
	УстановитьАтрибут(УзелСвойства, "Тип", ТипСвойства);	
	
КонецПроцедуры

Процедура _ВыгрузитьСубконто(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКС, 
	УзелКоллекцииСвойств = Неопределено, ОбъектКоллекции = Неопределено, Знач ВыгрузитьТолькоСсылку = Ложь)
	
	// Переменные-заглушки для поддержки механизма отладки кода обработчиков событий.
    Перем ТипПриемника, Пусто, Выражение, НеЗамещать, ПКОСвойств, УзелСвойства;
	
	// Инициализация значения
	Значение = Неопределено;
	ИмяПКО = "";
	ИмяПКОВидСубконто = "";
	
	// Обработчик ПередВыгрузкой
	Если ПКС.ЕстьОбработчикПередВыгрузкой Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			ВыгрузитьОбъект = Не ВыгрузитьТолькоСсылку;
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПКС_ПередВыгрузкойСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
															   ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, ТипПриемника, ИмяПКО,
															   ИмяПКОВидСубконто, Пусто, Выражение, УзелКоллекцииСвойств, НеЗамещать,
															   ВыгрузитьОбъект);
				
			Иначе
				
				Выполнить(ПКС.ПередВыгрузкой);
				
			КонецЕсли;
			
			ВыгрузитьТолькоСсылку = Не ВыгрузитьОбъект;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибкеОбработчикиПКС(55, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
				ПКО, ПКС, Источник, "ПередВыгрузкойСвойства", Значение);
			
		КонецПопытки;
		
		Если Отказ Тогда // Отказ от выгрузки
			
			Возврат;
			
		КонецЕсли;
		
	КонецЕсли;
	
	ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник);
	
	Если ПКС.ПриводитьКДлине <> 0 Тогда
				
		ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС);
						
	КонецЕсли;
		
	Для Каждого КлючИЗначение Из Значение Цикл
		
		ВидСубконто = КлючИЗначение.Ключ;
		Субконто = КлючИЗначение.Значение;
		ИмяПКО = "";
		
		// Обработчик ПриВыгрузке
		Если ПКС.ЕстьОбработчикПриВыгрузке Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				ВыгрузитьОбъект = Не ВыгрузитьТолькоСсылку;
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКС_ПриВыгрузкеСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, КлючИЗначение, ВидСубконто,
																Субконто, Пусто, ИмяПКО, ПКОСвойств,УзелСвойства, УзелКоллекцииСвойств,
																ИмяПКОВидСубконто, ВыгрузитьОбъект);
					
				Иначе
					
					Выполнить(ПКС.ПриВыгрузке);
					
				КонецЕсли;
				
				ВыгрузитьТолькоСсылку = Не ВыгрузитьОбъект;
				
			Исключение
				
				ЗаписатьИнформациюОбОшибкеОбработчикиПКС(56, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
					ПКО, ПКС, Источник, "ПриВыгрузкеСвойства", Значение);
				
			КонецПопытки;
			
			Если Отказ Тогда // Отказ от выгрузки субконто
				
				Продолжить;
				
			КонецЕсли;
			
		КонецЕсли;
		
		Если Субконто = Неопределено
			ИЛИ НайтиПравило(Субконто, ИмяПКО) = Неопределено Тогда
			
			Продолжить;
			
		КонецЕсли;
			
		УзелСубконто = СоздатьУзел(ПКС.Приемник);
			
		// Ключ
		УзелСвойства = СоздатьУзел("Свойство");
			
		Если ИмяПКОВидСубконто = "" Тогда
				
			ПКОКлюч = НайтиПравило(ВидСубконто);
				
		Иначе
				
			ПКОКлюч = НайтиПравило(, ИмяПКОВидСубконто);
				
		КонецЕсли;
			
		УстановитьАтрибут(УзелСвойства, "Имя", "Ключ");
		ВыгрузитьТипСвойстваЭлемента(УзелСвойства, ПКОКлюч.Приемник);
		
		УзелСсылки = ВыгрузитьПоПравилу(ВидСубконто,, ИсходящиеДанные,, ИмяПКОВидСубконто,, ИСТИНА, ПКОКлюч, , , , , Ложь);
			
		Если УзелСсылки <> Неопределено Тогда
				
			ДобавитьПодчиненный(УзелСвойства, УзелСсылки);
				
		КонецЕсли;
			
		ДобавитьПодчиненный(УзелСубконто, УзелСвойства);
		
		// Значение
		УзелСвойства = СоздатьУзел("Свойство");
			
		ПКОЗначение = НайтиПравило(Субконто, ИмяПКО);
		
		ТипПриемника = ПКОЗначение.Приемник;
		
		ЭтоNULL = Ложь;
		Пусто = одПустое(Субконто, ЭтоNULL);
		
		Если Пусто Тогда
			
			Если ЭтоNULL 
				Или Значение = Неопределено Тогда
				
				Продолжить;
				
			КонецЕсли;
			
			Если ПустаяСтрока(ТипПриемника) Тогда
				
				ТипПриемника = ОпределитьТипДанныхДляПриемника(Субконто);
								
			КонецЕсли;			
			
			УстановитьАтрибут(УзелСвойства, "Имя", "Значение");
			
			Если Не ПустаяСтрока(ТипПриемника) Тогда
				УстановитьАтрибут(УзелСвойства, "Тип", ТипПриемника);
			КонецЕсли;
							
			// Если тип множественный, то возможно это пустая ссылка и выгрузить ее нужно именно с указанием типа.
			одЗаписатьЭлемент(УзелСвойства, "Пусто");
			ДобавитьПодчиненный(УзелСубконто, УзелСвойства);
			
		Иначе
			
			ЭтоПравилоСГлобальнойВыгрузкой = Ложь;
			
			ВыгрузитьТолькоСсылку = Истина;
			Если ВыгружатьОбъектПоСсылке(Субконто, УзелДляОбмена) Тогда
						
				Если Не ОбъектПроходитФильтрРазрешенныхОбъектов(Субконто) Тогда
					
					// Выставляем признак того, что объект должен быть выгружен полностью.
					ВыгрузитьТолькоСсылку = Ложь;
					
					// Добавляем запись в регистр сопоставления.
					СтруктураЗаписи = Новый Структура;
					СтруктураЗаписи.Вставить("УзелИнформационнойБазы", УзелДляОбмена);
					СтруктураЗаписи.Вставить("УникальныйИдентификаторИсточника", Субконто);
					СтруктураЗаписи.Вставить("ОбъектВыгруженПоСсылке", Истина);
					
					РегистрыСведений.СоответствияОбъектовИнформационныхБаз.ДобавитьЗапись(СтруктураЗаписи, Истина);
					
					// Добавляем объект в массив выгруженных по ссылке объектов
					// для последующей регистрации объектов на текущем узле
					// и для присвоения номера текущего отправленного сообщения обмена.
					ВыгруженныеПоСсылкеОбъектыДобавитьЗначение(Субконто);
					
				КонецЕсли;
				
			КонецЕсли;
			
			УзелСсылки = ВыгрузитьПоПравилу(Субконто,, ИсходящиеДанные, , ИмяПКО, , ВыгрузитьТолькоСсылку, ПКОЗначение, , , , , Ложь, ЭтоПравилоСГлобальнойВыгрузкой);
			
			УстановитьАтрибут(УзелСвойства, "Имя", "Значение");
			ВыгрузитьТипСвойстваЭлемента(УзелСвойства, ТипПриемника);
						
				
			ТипУзлаСсылки = ТипЗнч(УзелСсылки);
				
			Если УзелСсылки = Неопределено Тогда
					
				Продолжить;
					
			КонецЕсли;
							
			ДобавитьСвойстваДляВыгрузки(УзелСсылки, ТипУзлаСсылки, УзелСвойства, ЭтоПравилоСГлобальнойВыгрузкой);
			
			ДобавитьПодчиненный(УзелСубконто, УзелСвойства);
			
		КонецЕсли;
		
		// Обработчик ПослеВыгрузки
		Если ПКС.ЕстьОбработчикПослеВыгрузки Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКС_ПослеВыгрузкиСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																  ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, КлючИЗначение, ВидСубконто,
																  Субконто, ИмяПКО, ИмяПКОВидСубконто, ПКОСвойств, УзелСвойства,
																  УзелСсылки, УзелКоллекцииСвойств, УзелСубконто);
					
				Иначе
					
					Выполнить(ПКС.ПослеВыгрузки);
					
				КонецЕсли;
				
			Исключение
				
				ЗаписатьИнформациюОбОшибкеОбработчикиПКС(57, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
					ПКО, ПКС, Источник, "ПослеВыгрузкиСвойства", Значение);
				
			КонецПопытки;
			
			Если Отказ Тогда // Отказ от выгрузки
				
				Продолжить;
				
			КонецЕсли;
			
		КонецЕсли;
		
		ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСубконто);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ДобавитьСвойстваДляВыгрузки(УзелСсылки, ТипУзлаСсылки, УзелСвойства, ЭтоПравилоСГлобальнойВыгрузкой)
	
	Если ТипУзлаСсылки = ТипСтрока Тогда
				
		Если СтрНайти(УзелСсылки, "<Ссылка") > 0 Тогда
					
			УзелСвойства.ЗаписатьБезОбработки(УзелСсылки);
					
		Иначе
			
			одЗаписатьЭлемент(УзелСвойства, "Значение", УзелСсылки);
					
		КонецЕсли;
				
	ИначеЕсли ТипУзлаСсылки = ТипЧисло Тогда
		
		Если ЭтоПравилоСГлобальнойВыгрузкой Тогда
		
			одЗаписатьЭлемент(УзелСвойства, "ГНпп", УзелСсылки);
			
		Иначе     		
			
			одЗаписатьЭлемент(УзелСвойства, "Нпп", УзелСсылки);
			
		КонецЕсли;
				
	Иначе
				
		ДобавитьПодчиненный(УзелСвойства, УзелСсылки);
				
	КонецЕсли;
	
КонецПроцедуры

Процедура ОпределитьВозможностьУстановкиЗначения(Значение, ТипЗначения, ТипПриемника, СвойствоУстановлено, НужноУказатьТип)
	
	СвойствоУстановлено = Истина;
		
	Если ТипЗначения = ТипСтрока Тогда
				
		Если ТипПриемника = "Строка"  Тогда
		ИначеЕсли ТипПриемника = "Число"  Тогда
					
			Значение = Число(Значение);
					
		ИначеЕсли ТипПриемника = "Булево"  Тогда
					
			Значение = Булево(Значение);
					
		ИначеЕсли ТипПриемника = "Дата"  Тогда
					
			Значение = Дата(Значение);
					
		ИначеЕсли ТипПриемника = "ХранилищеЗначения"  Тогда
					
			Значение = Новый ХранилищеЗначения(Значение);
					
		ИначеЕсли ТипПриемника = "УникальныйИдентификатор" Тогда
					
			Значение = Новый УникальныйИдентификатор(Значение);
					
		ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда
					
			ТипПриемника = "Строка";
			НужноУказатьТип = Истина;
			
		КонецЕсли;
								
	ИначеЕсли ТипЗначения = ТипЧисло Тогда
				
		Если ТипПриемника = "Число"
			ИЛИ ТипПриемника = "Строка" Тогда
		ИначеЕсли ТипПриемника = "Булево"  Тогда
					
			Значение = Булево(Значение);
					
		ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда
					
			ТипПриемника = "Число";
			НужноУказатьТип = Истина;
			
		Иначе
			
			СвойствоУстановлено = Ложь;
					
		КонецЕсли;
								
	ИначеЕсли ТипЗначения = ТипДата Тогда
				
		Если ТипПриемника = "Дата"  Тогда
		ИначеЕсли ТипПриемника = "Строка"  Тогда
					
			Значение = Лев(Строка(Значение), 10);
					
		ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда
					
			ТипПриемника = "Дата";
			НужноУказатьТип = Истина;
			
		Иначе
			
			СвойствоУстановлено = Ложь;
					
		КонецЕсли;				
						
	ИначеЕсли ТипЗначения = ТипБулево Тогда
				
		Если ТипПриемника = "Булево"  Тогда
		ИначеЕсли ТипПриемника = "Число"  Тогда
					
			Значение = Число(Значение);
					
		ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда
					
			ТипПриемника = "Булево";
			НужноУказатьТип = Истина;
			
		Иначе
			
			СвойствоУстановлено = Ложь;
					
		КонецЕсли;				
						
	ИначеЕсли ТипЗначения = ТипХранилищеЗначения Тогда
				
		Если ПустаяСтрока(ТипПриемника) Тогда
					
			ТипПриемника = "ХранилищеЗначения";
			НужноУказатьТип = Истина;
					
		ИначеЕсли ТипПриемника <> "ХранилищеЗначения"  Тогда
					
			СвойствоУстановлено = Ложь;
					
		КонецЕсли;				
						
	ИначеЕсли ТипЗначения = ТипУникальныйИдентификатор Тогда
				
		Если ТипПриемника = "УникальныйИдентификатор" Тогда
		ИначеЕсли ТипПриемника = "Строка" Тогда
			
			Значение = Строка(Значение);
			
		ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда
			
			ТипПриемника = "УникальныйИдентификатор";
			НужноУказатьТип = Истина;
			
		Иначе
			
			СвойствоУстановлено = Ложь;
					
		КонецЕсли;				
						
	ИначеЕсли ТипЗначения = ТипВидДвиженияНакопления Тогда
				
		Значение = Строка(Значение);		
		
	ИначеЕсли ТипЗначения = ТипОписаниеТипов Тогда
		
		Значение = Строка(Значение);
		
	Иначе
		
		СвойствоУстановлено = Ложь;
		
	КонецЕсли;	
	
КонецПроцедуры

Функция ОпределитьТипДанныхДляПриемника(Значение)
	
	ТипПриемника = одТипЗначенияСтрокой(Значение);
	
	// Есть ли хоть какое ПКО с типом приемника ТипПриемника
	// если правила нет - то "", если есть , то то что нашли оставляем.
	СтрокаТаблицы = ТаблицаПравилКонвертации.Найти(ТипПриемника, "Приемник");
	
	Если СтрокаТаблицы = Неопределено Тогда
		
		Если Не (ТипПриемника = "Строка"
			ИЛИ ТипПриемника = "Число"
			ИЛИ ТипПриемника = "Дата"
			ИЛИ ТипПриемника = "Булево"
			ИЛИ ТипПриемника = "ХранилищеЗначения") Тогда
			
			ТипПриемника = "";
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат ТипПриемника;
	
КонецФункции

Процедура ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС)
	
	Значение = ПривестиНомерКДлине(Строка(Значение), ПКС.ПриводитьКДлине);
		
КонецПроцедуры

Процедура ВыполнитьЗаписьСтруктурыВXML(СтруктураДанных, УзелКоллекцииСвойств, ЭтоОбычноеСвойство = Истина)
	
	УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента(?(ЭтоОбычноеСвойство, "Свойство", "ЗначениеПараметра"));
	
	Для Каждого ЭлементКоллекции Из СтруктураДанных Цикл
		
		Если ЭлементКоллекции.Ключ = "Выражение"
			ИЛИ ЭлементКоллекции.Ключ = "Значение"
			ИЛИ ЭлементКоллекции.Ключ = "Нпп"
			ИЛИ ЭлементКоллекции.Ключ = "ГНпп" Тогда
			
			одЗаписатьЭлемент(УзелКоллекцииСвойств, ЭлементКоллекции.Ключ, ЭлементКоллекции.Значение);
			
		ИначеЕсли ЭлементКоллекции.Ключ = "Ссылка" Тогда
			
			УзелКоллекцииСвойств.ЗаписатьБезОбработки(ЭлементКоллекции.Значение);
			
		Иначе
			
			УстановитьАтрибут(УзелКоллекцииСвойств, ЭлементКоллекции.Ключ, ЭлементКоллекции.Значение);
			
		КонецЕсли;
		
	КонецЦикла;
	
	УзелКоллекцииСвойств.ЗаписатьКонецЭлемента();		
	
КонецПроцедуры

Процедура СоздатьСложнуюИнформациюДляЗаписиВXML(СтруктураДанных, УзелСвойства, НуженУзелXML, ИмяПриемника, ИмяПараметра)
	
	Если ПустаяСтрока(ИмяПараметра) Тогда
		
		СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураДанных, УзелСвойства, НуженУзелXML, ИмяПриемника, "Свойство");
		
	Иначе
		
		СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураДанных, УзелСвойства, НуженУзелXML, ИмяПараметра, "ЗначениеПараметра");
		
	КонецЕсли;
	
КонецПроцедуры

Процедура СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураДанных, УзелСвойства, НуженУзелXML, ИмяУзла, НаименованиеУзлаXML = "Свойство")
	
	Если НуженУзелXML Тогда
		
		УзелСвойства = СоздатьУзел(НаименованиеУзлаXML);
		УстановитьАтрибут(УзелСвойства, "Имя", ИмяУзла);
		
	Иначе
		
		СтруктураДанных = Новый Структура("Имя", ИмяУзла);
		
	КонецЕсли;		
	
КонецПроцедуры

Процедура ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, ИмяАтрибута, ЗначениеАтрибута)
	
	Если СтруктураУзлаСвойств <> Неопределено Тогда
		СтруктураУзлаСвойств.Вставить(ИмяАтрибута, ЗначениеАтрибута);
	Иначе
		УстановитьАтрибут(УзелСвойства, ИмяАтрибута, ЗначениеАтрибута);
	КонецЕсли;
	
КонецПроцедуры

Процедура ДобавитьЗначениеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, ИмяАтрибута, ЗначениеАтрибута)
	
	Если СтруктураУзлаСвойств <> Неопределено Тогда
		СтруктураУзлаСвойств.Вставить(ИмяАтрибута, ЗначениеАтрибута);
	Иначе
		одЗаписатьЭлемент(УзелСвойства, ИмяАтрибута, ЗначениеАтрибута);
	КонецЕсли;
	
КонецПроцедуры

Процедура ДобавитьПроизвольныеДанныеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, ИмяАтрибута, ЗначениеАтрибута)
	
	Если СтруктураУзлаСвойств <> Неопределено Тогда
		СтруктураУзлаСвойств.Вставить(ИмяАтрибута, ЗначениеАтрибута);
	Иначе
		УзелСвойства.ЗаписатьБезОбработки(ЗначениеАтрибута);
	КонецЕсли;
	
КонецПроцедуры

Процедура ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелСвойства, ЭтоОбычноеСвойство = Истина)
	
	Если СтруктураУзлаСвойств <> Неопределено Тогда
		ВыполнитьЗаписьСтруктурыВXML(СтруктураУзлаСвойств, УзелКоллекцииСвойств, ЭтоОбычноеСвойство);
	Иначе
		ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСвойства);
	КонецЕсли;
	
КонецПроцедуры

// Формирует узлы свойств объекта приемника в соответствии с указанной коллекцией правил конвертации свойств.
//
// Параметры:
//  Источник             - Произвольный - произвольный источник данных.
//  Приемник             - ЗаписьXML - xml-узел объекта приемника.
//  ВходящиеДанные       - Произвольный - произвольные вспомогательные данные, передаваемые правилу
//                         для выполнения конвертации.
//  ИсходящиеДанные      - Произвольный - произвольные вспомогательные данные, передаваемые правилам
//                         конвертации объектов свойств.
//  ПКО                  - СтрокаТаблицыЗначений - ссылка на правило конвертации объектов.
//  КоллекцияПКС         - см. КоллекцияПравилаКонвертацииСвойств
//  УзелКоллекцииСвойств - ЗаписьXML - xml-узел коллекции свойств.
//  ОбъектКоллекции      - Произвольный - если указан, то выполняется выгрузка свойств объекта коллекции, иначе Источника.
//  ИмяПредопределенногоЭлемента - Строка - если указан, то в свойствах пишется имя предопределенного элемента.
// 
Процедура ВыгрузитьСвойства(Источник, 
							Приемник, 
							ВходящиеДанные, 
							ИсходящиеДанные, 
							ПКО, 
							КоллекцияПКС, 
							УзелКоллекцииСвойств = Неопределено, 
							ОбъектКоллекции = Неопределено, 
							ИмяПредопределенногоЭлемента = Неопределено, 
							Знач ПКОВыгрузитьТолькоСсылку = Истина, 
							Знач ЭтоВыгрузкаСсылки = Ложь, 
							Знач ВыгружаетсяОбъект = Ложь, 
							КлючПоискаСсылки = "", 
							НеИспользоватьПравилаСГлобальнойВыгрузкойИНеЗапоминатьВыгруженные = Ложь,
							ЗначениеСсылкиВДругойИБ = "",
							СписокВременныхФайлов = Неопределено, 
							ВыгрузкаСтрокиНабораЗаписейРегистра = Ложь,
							СтекВыгрузкиОбъекта = Неопределено)
							
	// Переменные-заглушки для поддержки механизма отладки кода обработчиков событий.
	Перем КлючИЗначение, ВидСубконто, Субконто, ИмяПКОВидСубконто, УзелСубконто;

							
	Если УзелКоллекцииСвойств = Неопределено Тогда
		
		УзелКоллекцииСвойств = Приемник;
		
	КонецЕсли;
	
	ВыборкаСвойств = Неопределено;
	
	Если ЭтоВыгрузкаСсылки Тогда
				
		// Выгружаем имя предопределенного если оно указано.
		Если ИмяПредопределенногоЭлемента <> Неопределено Тогда
			
			УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента("Свойство");
			УстановитьАтрибут(УзелКоллекцииСвойств, "Имя", "{ИмяПредопределенногоЭлемента}");
			одЗаписатьЭлемент(УзелКоллекцииСвойств, "Значение", ИмяПредопределенногоЭлемента);
			УзелКоллекцииСвойств.ЗаписатьКонецЭлемента();
			
		КонецЕсли;
		
	КонецЕсли;
	
	Для каждого ПКС Из КоллекцияПКС Цикл
		
		ВыгрузитьТолькоСсылку = ПКОВыгрузитьТолькоСсылку;
		
		Если ПКС.УпрощеннаяВыгрузкаСвойства Тогда
			
			
			 //	Создаем узел свойства
			УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента("Свойство");
			УстановитьАтрибут(УзелКоллекцииСвойств, "Имя", ПКС.Приемник);
			
			Если Не ПустаяСтрока(ПКС.ТипПриемника) Тогда
				
				УстановитьАтрибут(УзелКоллекцииСвойств, "Тип", ПКС.ТипПриемника);
				
			КонецЕсли;
			
			Если ПКС.НеЗамещать Тогда
				
				УстановитьАтрибут(УзелКоллекцииСвойств, "НеЗамещать",	"true");
				
			КонецЕсли;
			
			Если ПКС.ПоискПоДатеНаРавенство  Тогда
				
				УстановитьАтрибут(УзелКоллекцииСвойств, "ПоискПоДатеНаРавенство", "true");
				
			КонецЕсли;
			
			Значение = Неопределено;
			ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник, ВыборкаСвойств);
			
			Если ПКС.ПриводитьКДлине <> 0 Тогда
				
				ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС);
								
			КонецЕсли;
			
			ЭтоNULL = Ложь;
			Пусто = одПустое(Значение, ЭтоNULL);
						
			Если Пусто Тогда
				
				УзелКоллекцииСвойств.ЗаписатьКонецЭлемента();
				Продолжить;
				
			КонецЕсли;
			
			одЗаписатьЭлемент(УзелКоллекцииСвойств, 	"Значение", Значение);
			
			УзелКоллекцииСвойств.ЗаписатьКонецЭлемента();
			Продолжить;					
					
		ИначеЕсли ПКС.ВидПриемника = "ВидыСубконтоСчета" Тогда
			
			_ВыгрузитьСубконто(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, 
				ПКС, УзелКоллекцииСвойств, ОбъектКоллекции, ВыгрузитьТолькоСсылку);
			
			Продолжить;
			
		ИначеЕсли ПКС.Имя = "{УникальныйИдентификатор}" Тогда
			
			СсылкаНаИсточник = ОпределитьСсылкуПоОбъектуИлиСсылке(Источник, ВыгружаетсяОбъект);
			
			УникальныйИдентификатор = СсылкаНаИсточник.УникальныйИдентификатор();
			
			УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента("Свойство");
			УстановитьАтрибут(УзелКоллекцииСвойств, "Имя", "{УникальныйИдентификатор}");
			УстановитьАтрибут(УзелКоллекцииСвойств, "Тип", "Строка");
			УстановитьАтрибут(УзелКоллекцииСвойств, "ТипИсточника", ПКО.ТипИсточника);
			УстановитьАтрибут(УзелКоллекцииСвойств, "ТипПриемника", ПКО.ТипПриемника);
			одЗаписатьЭлемент(УзелКоллекцииСвойств, "Значение", УникальныйИдентификатор);
			УзелКоллекцииСвойств.ЗаписатьКонецЭлемента();
			
			Продолжить;
			
		ИначеЕсли ПКС.ЭтоГруппа Тогда
			
			ВыгрузитьГруппуСвойств(
				Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКС, УзелКоллекцииСвойств, 
				ВыгрузитьТолькоСсылку, СписокВременныхФайлов, ВыгрузкаСтрокиНабораЗаписейРегистра);
			
			Продолжить;
			
		КонецЕсли;
		
		//	Инициализируем значение, которое будем конвертировать.
		Значение 	 = Неопределено;
		ИмяПКО		 = ПКС.ПравилоКонвертации;
		НеЗамещать   = ПКС.НеЗамещать;
		
		Пусто		 = Ложь;
		Выражение	 = Неопределено;
		ТипПриемника = ПКС.ТипПриемника;

		ЭтоNULL      = Ложь;
		
		// Обработчик ПередВыгрузкой
		Если ПКС.ЕстьОбработчикПередВыгрузкой Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				ВыгрузитьОбъект = Не ВыгрузитьТолькоСсылку;
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКС_ПередВыгрузкойСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																   ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, ТипПриемника, ИмяПКО,
																   ИмяПКОВидСубконто, Пусто, Выражение, УзелКоллекцииСвойств, НеЗамещать,
																   ВыгрузитьОбъект);
					
				Иначе
					
					Выполнить(ПКС.ПередВыгрузкой);
					
				КонецЕсли;
				
				ВыгрузитьТолькоСсылку = Не ВыгрузитьОбъект;
				
			Исключение
				
				ЗаписатьИнформациюОбОшибкеОбработчикиПКС(55, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
					ПКО, ПКС, Источник, "ПередВыгрузкойСвойства", Значение);
				
			КонецПопытки;
			
			Если Отказ Тогда	//	Отказ от выгрузки свойства
				
				Продолжить;
				
			КонецЕсли;
			
		КонецЕсли;
		
		// Создаем узел свойства
		СтруктураУзлаСвойств = Неопределено;
		УзелСвойства = Неопределено;
		
		СоздатьСложнуюИнформациюДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, ПКС.НуженУзелXMLПриВыгрузке, ПКС.Приемник, ПКС.ИмяПараметраДляПередачи);
							
		Если НеЗамещать Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "НеЗамещать", "true");			
						
		КонецЕсли;
		
		Если ПКС.ПоискПоДатеНаРавенство  Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "ПоискПоДатеНаРавенство", "true");
			
		КонецЕсли;
		
		//	Возможно правило конвертации уже определено.
		Если Не ПустаяСтрока(ИмяПКО) Тогда
			
			ПКОСвойств = Правила[ИмяПКО];
			
		Иначе
			
			ПКОСвойств = Неопределено;
			
		КонецЕсли;
		
		Если Не ПустаяСтрока(ТипПриемника) Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Тип", ТипПриемника);
			
		ИначеЕсли ПКОСвойств <> Неопределено Тогда
			
			// Попытка определить тип свойства приемника.
			ТипПриемника = ПКОСвойств.Приемник;
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Тип", ТипПриемника);
			
		КонецЕсли;
		
		Если Не ПустаяСтрока(ИмяПКО)
			И ПКОСвойств <> Неопределено
			И ПКОСвойств.ЕстьОбработчикПоследовательностьПолейПоиска = Истина Тогда
			
			ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "ИмяПКО", ИмяПКО);
			
		КонецЕсли;
		
		ЭтоОбычноеСвойство = ПустаяСтрока(ПКС.ИмяПараметраДляПередачи);
		
		//	Определяем конвертируемое значение.
		Если Выражение <> Неопределено Тогда
			
			ДобавитьЗначениеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Выражение", Выражение);
			
			ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелСвойства, ЭтоОбычноеСвойство);
			Продолжить;
			
		ИначеЕсли Пусто Тогда
			
			ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелСвойства, ЭтоОбычноеСвойство);
			Продолжить;
			
		Иначе
			
			ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник, ВыборкаСвойств);
			
			Если ПКС.ПриводитьКДлине <> 0 Тогда
				
				ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС);
								
			КонецЕсли;
						
		КонецЕсли;

		СтароеЗначениеДоОбработчикаПриВыгрузке = Значение;
		Пусто = одПустое(Значение, ЭтоNULL);
		
		// Обработчик ПриВыгрузке
		Если ПКС.ЕстьОбработчикПриВыгрузке Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				ВыгрузитьОбъект = Не ВыгрузитьТолькоСсылку;
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКС_ПриВыгрузкеСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, КлючИЗначение, ВидСубконто,
																Субконто, Пусто, ИмяПКО, ПКОСвойств,УзелСвойства, УзелКоллекцииСвойств,
																ИмяПКОВидСубконто, ВыгрузитьОбъект);
					
				Иначе
					
					Выполнить(ПКС.ПриВыгрузке);
					
				КонецЕсли;
				
				ВыгрузитьТолькоСсылку = Не ВыгрузитьОбъект;
				
			Исключение
				
				ЗаписатьИнформациюОбОшибкеОбработчикиПКС(56, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
					ПКО, ПКС, Источник, "ПриВыгрузкеСвойства", Значение);
				
			КонецПопытки;
			
			Если Отказ Тогда	//	Отказ от выгрузки свойства
				
				Продолжить;
				
			КонецЕсли;
			
		КонецЕсли;
		
		// Инициализируем еще раз переменную Пусто, может быть Значение было изменено 
		// в обработчике "При выгрузке".
		Если СтароеЗначениеДоОбработчикаПриВыгрузке <> Значение Тогда
			
			Пусто = одПустое(Значение, ЭтоNULL);
			
		КонецЕсли;

		Если Пусто Тогда
			
			Если ЭтоNULL Тогда
				
				Значение = Неопределено;
				
			КонецЕсли;
			
			Если Значение <> Неопределено 
				И ПустаяСтрока(ТипПриемника) Тогда
				
				ТипПриемника = ОпределитьТипДанныхДляПриемника(Значение);
				
				Если Не ПустаяСтрока(ТипПриемника) Тогда
					
					ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Тип", ТипПриемника);
					
				КонецЕсли;
								
			КонецЕсли;			
			
			ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелСвойства, ЭтоОбычноеСвойство);
			Продолжить;
			
		КонецЕсли;
      		
		УзелСсылки = Неопределено;
		
		Если ПКОСвойств = Неопределено
			И ПустаяСтрока(ИмяПКО) Тогда
			
			СвойствоУстановлено = Ложь;
			ТипЗначения = ТипЗнч(Значение);
			НужноУказатьТип = Ложь;
			ОпределитьВозможностьУстановкиЗначения(Значение, ТипЗначения, ТипПриемника, СвойствоУстановлено, НужноУказатьТип);
						
			Если СвойствоУстановлено Тогда
				
				// если нужно тип указываем
				Если НужноУказатьТип Тогда
					
					ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Тип", ТипПриемника);
					
				КонецЕсли;
				
				ДобавитьЗначениеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Значение", Значение);
								              				
			Иначе
				
				МенеджерЗначения = Менеджеры[ТипЗначения];
				
				Если МенеджерЗначения = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				
				ПКОСвойств = МенеджерЗначения.ПКО; // см. НайтиПравило
				
				Если ПКОСвойств = Неопределено Тогда
					Продолжить;
				КонецЕсли;
					
				ИмяПКО = ПКОСвойств.Имя;
				
			КонецЕсли;
			
		КонецЕсли;
		
		Если (ПКОСвойств <> Неопределено) 
			Или (Не ПустаяСтрока(ИмяПКО)) Тогда
			
			Если ВыгрузитьТолькоСсылку Тогда
				
				Если ВыгружатьОбъектПоСсылке(Значение, УзелДляОбмена) Тогда
					
					Если Не ОбъектПроходитФильтрРазрешенныхОбъектов(Значение) Тогда
						
						// Выставляем признак того, что объект должен быть выгружен полностью.
						ВыгрузитьТолькоСсылку = Ложь;
						
						// Добавляем запись в регистр сопоставления.
						СтруктураЗаписи = Новый Структура;
						СтруктураЗаписи.Вставить("УзелИнформационнойБазы", УзелДляОбмена);
						СтруктураЗаписи.Вставить("УникальныйИдентификаторИсточника", Значение);
						СтруктураЗаписи.Вставить("ОбъектВыгруженПоСсылке", Истина);
						
						РегистрыСведений.СоответствияОбъектовИнформационныхБаз.ДобавитьЗапись(СтруктураЗаписи, Истина);
						
						// Добавляем объект в массив выгруженных по ссылке объектов
						// для последующей регистрации объектов на текущем узле
						// и для присвоения номера текущего отправленного сообщения обмена.
						ВыгруженныеПоСсылкеОбъектыДобавитьЗначение(Значение);
						
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЕсли;
			
			Если ЗначениеЗаполнено(СтекВыгрузкиОбъекта) Тогда
				ОтветвлениеСтекаВыгрузки = ОбщегоНазначения.СкопироватьРекурсивно(СтекВыгрузкиОбъекта);
			Иначе
				ОтветвлениеСтекаВыгрузки = Новый Массив;
			КонецЕсли;
			
			ПравилоСГлобальнойВыгрузкой = Ложь;
			УзелСсылки = ВыгрузитьПоПравилу(Значение, , ИсходящиеДанные, , ИмяПКО, , ВыгрузитьТолькоСсылку, ПКОСвойств, , , , , Ложь, 
				ПравилоСГлобальнойВыгрузкой, НеИспользоватьПравилаСГлобальнойВыгрузкойИНеЗапоминатьВыгруженные, ОтветвлениеСтекаВыгрузки);
	
			Если УзелСсылки = Неопределено Тогда
						
				Продолжить;
						
			КонецЕсли;
			
			Если ПустаяСтрока(ТипПриемника) Тогда
						
				ТипПриемника  = ПКОСвойств.Приемник;
				ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Тип", ТипПриемника);
														
			КонецЕсли;			
				
			ТипУзлаСсылки = ТипЗнч(УзелСсылки);
						
			Если ТипУзлаСсылки = ТипСтрока Тогда
				
				Если СтрНайти(УзелСсылки, "<Ссылка") > 0 Тогда
								
					ДобавитьПроизвольныеДанныеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Ссылка", УзелСсылки);
											
				Иначе
					
					ДобавитьЗначениеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Значение", УзелСсылки);
																	
				КонецЕсли;
						
			ИначеЕсли ТипУзлаСсылки = ТипЧисло Тогда
				
				Если ПравилоСГлобальнойВыгрузкой Тогда
					ДобавитьЗначениеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "ГНпп", УзелСсылки);
				Иначе
					ДобавитьЗначениеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Нпп", УзелСсылки);
				КонецЕсли;
														
			Иначе
				
				УзелСсылки.ЗаписатьКонецЭлемента();
				ИнформацияДляЗаписиВФайл = УзелСсылки.Закрыть();
				
				ДобавитьПроизвольныеДанныеДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, "Ссылка", ИнформацияДляЗаписиВФайл);
										
			КонецЕсли;
													
		КонецЕсли;
		
		
		
		// Обработчик ПослеВыгрузки
		
		Если ПКС.ЕстьОбработчикПослеВыгрузки Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_ПКС_ПослеВыгрузкиСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
																  ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, КлючИЗначение, ВидСубконто,
																  Субконто, ИмяПКО, ИмяПКОВидСубконто, ПКОСвойств, УзелСвойства,
																  УзелСсылки, УзелКоллекцииСвойств, УзелСубконто);
					
				Иначе
					
					Выполнить(ПКС.ПослеВыгрузки);
					
				КонецЕсли;
				
			Исключение
				
				ЗаписатьИнформациюОбОшибкеОбработчикиПКС(57, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
					ПКО, ПКС, Источник, "ПослеВыгрузкиСвойства", Значение);
				
			КонецПопытки;
			
			Если Отказ Тогда	//	Отказ от выгрузки свойства
				
				Продолжить;
				
			КонецЕсли;
			
		КонецЕсли;
		
		ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелСвойства, ЭтоОбычноеСвойство);
		
	КонецЦикла; // по ПКС
	
КонецПроцедуры

Процедура ОпределитьПКОПоПараметрам(ПКО, Источник, ИмяПКО)
	
	// Поиск ПКО
	Если ПКО = Неопределено Тогда
		
        ПКО = НайтиПравило(Источник, ИмяПКО);
		
	ИначеЕсли (Не ПустаяСтрока(ИмяПКО))
		И ПКО.Имя <> ИмяПКО Тогда
		
		ПКО = НайтиПравило(Источник, ИмяПКО);
				
	КонецЕсли;	
	
КонецПроцедуры

Функция НайтиСтруктуруСвойствПоПараметрам(ПКО, Источник)
	
	СтруктураСвойств = Менеджеры[ПКО.Источник];
	Если СтруктураСвойств = Неопределено Тогда
		СтруктураСвойств = Менеджеры[ТипЗнч(Источник)];
	КонецЕсли;	
	
	Возврат СтруктураСвойств;
	
КонецФункции

Функция ОпределитьСсылкуПоОбъектуИлиСсылке(Источник, ВыгружаетсяОбъект)
	
	Если ВыгружаетсяОбъект Тогда
		Возврат Источник.Ссылка;
	Иначе
		Возврат Источник;
	КонецЕсли;
	
КонецФункции

Функция ОпределитьВнутреннеПредставлениеДляПоиска(Источник, СтруктураСвойств)
	
	Если СтруктураСвойств.ИмяТипа = "Перечисление" Тогда
		Возврат Источник;
	Иначе
		Возврат ЗначениеВСтрокуВнутр(Источник);
	КонецЕсли
	
КонецФункции

Процедура ПровестиОбновлениеДанныхВВыгружаемыхДанных()
	
	Если СоответствиеДанныхДляОбновленияВыгруженныхЭлементов.Количество() > 0 Тогда
		
		СоответствиеДанныхДляОбновленияВыгруженныхЭлементов.Очистить();
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ПровестиУстановкуПризнаковВыгруженныхОбъектовВФайл()
	
	НППЗаписанногоВФайл = СчетчикНПП;
	
КонецПроцедуры

Процедура ЗаписатьПриоритетОбъектовОбмена(ПриоритетОбъектовОбмена, Узел)
	
	Если ЗначениеЗаполнено(ПриоритетОбъектовОбмена)
		И ПриоритетОбъектовОбмена <> Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаВыше Тогда
		
		Если ПриоритетОбъектовОбмена = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаНиже Тогда
			УстановитьАтрибут(Узел, "ПриоритетОбъектаОбмена", "Ниже");
		ИначеЕсли ПриоритетОбъектовОбмена = Перечисления.ПриоритетыОбъектовОбмена.ПриоритетОбъектаОбменаСовпадает Тогда
			УстановитьАтрибут(Узел, "ПриоритетОбъектаОбмена", "Совпадает");
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ВыгрузитьИнформациюОЗарегистрированномОбъекте(НаборЗаписейДляВыгрузки)
	
	Если НаборЗаписейДляВыгрузки.Количество() = 0 Тогда // выгружаем пустой набор РС
		
		Отбор = Новый Структура;
		Отбор.Вставить("УникальныйИдентификаторИсточника", НаборЗаписейДляВыгрузки.Отбор.УникальныйИдентификаторИсточника.Значение);
		Отбор.Вставить("УникальныйИдентификаторПриемника", НаборЗаписейДляВыгрузки.Отбор.УникальныйИдентификаторПриемника.Значение);
		Отбор.Вставить("ТипИсточника",                     НаборЗаписейДляВыгрузки.Отбор.ТипИсточника.Значение);
		Отбор.Вставить("ТипПриемника",                     НаборЗаписейДляВыгрузки.Отбор.ТипПриемника.Значение);
		
		ВыгрузитьЗаписьСоответствияОбъектовИнформационныхБаз(Отбор, Истина);
		
	Иначе
		
		Для Каждого СтрокаНабора Из НаборЗаписейДляВыгрузки Цикл
			
			ВыгрузитьЗаписьСоответствияОбъектовИнформационныхБаз(СтрокаНабора, Ложь);
			
		КонецЦикла;
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ВыгрузитьЗаписьСоответствияОбъектовИнформационныхБаз(СтрокаНабора, ПустойНабор)
	
	Приемник = СоздатьУзел("ИнформацияОРегистрацииОбъекта");
	
	УстановитьАтрибут(Приемник, "УникальныйИдентификаторИсточника", Строка(СтрокаНабора.УникальныйИдентификаторИсточника.УникальныйИдентификатор()));
	УстановитьАтрибут(Приемник, "УникальныйИдентификаторПриемника",        СтрокаНабора.УникальныйИдентификаторПриемника);
	УстановитьАтрибут(Приемник, "ТипИсточника",                            СтрокаНабора.ТипИсточника);
	УстановитьАтрибут(Приемник, "ТипПриемника",                            СтрокаНабора.ТипПриемника);
	
	УстановитьАтрибут(Приемник, "ПустойНабор", ПустойНабор);
	
	Приемник.ЗаписатьКонецЭлемента(); // ИнформацияОРегистрацииОбъекта
	
	ЗаписатьВФайл(Приемник);
	
КонецПроцедуры

Процедура ВызватьСобытияПередВыгрузкойОбъекта(Объект, Правило, Свойства=Неопределено, ВходящиеДанные=Неопределено, 
	НеВыгружатьОбъектыСвойствПоСсылкам = Ложь, ИмяПКО, Отказ, ИсходящиеДанные)
	
	Если ФлагКомментироватьОбработкуОбъектов Тогда
		
		ОписаниеТипов = Новый ОписаниеТипов("Строка");
		ОбъектСтрока  = ОписаниеТипов.ПривестиЗначение(Объект);
		Если ОбъектСтрока = "" Тогда
			ПрОбъекта = ОбъектСтрока + "  (" + ТипЗнч(Объект) + ")";
		Иначе
			ПрОбъекта = ТипЗнч(Объект);
		КонецЕсли;
		
		ИмяСобытия = НСтр("ru = 'Выгрузка объекта: %1'");
		ИмяСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ИмяСобытия, ПрОбъекта);
		
		ЗаписатьВПротоколВыполнения(ИмяСобытия, , Ложь, 1, 7);
		
	КонецЕсли;
	
	
	ИмяПКО			= Правило.ПравилоКонвертации;
	Отказ			= Ложь;
	ИсходящиеДанные	= Неопределено;
	
	
	// Глобальный обработчик ПередВыгрузкойОбъекта.
	Если ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПередВыгрузкойОбъекта(ФайлОбмена, Отказ, ИмяПКО, Правило, ВходящиеДанные, ИсходящиеДанные, Объект);
				
			Иначе
				
				Выполнить(Конвертация.ПередВыгрузкойОбъекта);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиПВД(65, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
				Правило.Имя, НСтр("ru = 'ПередВыгрузкойОбъектаВыборки (глобальный)'"), Объект);
		КонецПопытки;
		
		Если Отказ Тогда
			Возврат;
		КонецЕсли;
		
	КонецЕсли;
	
	// Обработчик ПередВыгрузкой
	Если Не ПустаяСтрока(Правило.ПередВыгрузкой) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПВД_ПередВыгрузкойОбъекта(ФайлОбмена, Отказ, ИмяПКО, Правило, ВходящиеДанные, ИсходящиеДанные, Объект);
				
			Иначе
				
				Выполнить(Правило.ПередВыгрузкой);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиПВД(33, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, "ПередВыгрузкойОбъектаВыборки", Объект);
		КонецПопытки;
		
	КонецЕсли;		
	
КонецПроцедуры

Процедура ВызватьСобытияПослеВыгрузкиОбъекта(Объект, Правило, Свойства=Неопределено, ВходящиеДанные=Неопределено, 
	НеВыгружатьОбъектыСвойствПоСсылкам = Ложь, ИмяПКО, Отказ, ИсходящиеДанные)
	
	Перем УзелСсылки; // Переменная-заглушка
	
	// Глобальный обработчик ПослеВыгрузкиОбъекта.
	Если ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПослеВыгрузкиОбъекта(ФайлОбмена, Объект, ИмяПКО, ВходящиеДанные, ИсходящиеДанные, УзелСсылки);
				
			Иначе
				
				Выполнить(Конвертация.ПослеВыгрузкиОбъекта);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиПВД(69, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, НСтр("ru = 'ПослеВыгрузкиОбъектаВыборки (глобальный)'"), Объект);
		КонецПопытки;
	КонецЕсли;
	
	// Обработчик ПослеВыгрузки
	Если Не ПустаяСтрока(Правило.ПослеВыгрузки) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_ПВД_ПослеВыгрузкиОбъекта(ФайлОбмена, Объект, ИмяПКО, ВходящиеДанные, ИсходящиеДанные, УзелСсылки, Правило);
				
			Иначе
				
				Выполнить(Правило.ПослеВыгрузки);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиПВД(34, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				Правило.Имя, "ПослеВыгрузкиОбъектаВыборки", Объект);
		КонецПопытки;
		
	КонецЕсли;
	
КонецПроцедуры

// Производит выгрузку объекта выборки в соответствии с указанным правилом.
//
// Параметры:
//  Объект          - выгружаемый объект выборки.
//  ПравилоВыгрузки - ссылка на правило выгрузки данных.
//  Свойства        - свойства объекта метаданного выгружаемого объекта.
//  ВходящиеДанные  - произвольные вспомогательные данные.
// 
Функция ВыгрузкаОбъектаВыборки(Объект, 
								ПравилоВыгрузки, 
								Свойства=Неопределено, 
								ВходящиеДанные = Неопределено,
								НеВыгружатьОбъектыСвойствПоСсылкам = Ложь, 
								ВыгрузкаСтрокиНабораЗаписей = Ложь, 
								УзелПредка = Неопределено, 
								ИмяКонстантыДляВыгрузки = "",
								ИмяПКО = "",
								ВызыватьСобытия = Истина)
								
	Отказ			= Ложь;
	ИсходящиеДанные	= Неопределено;
		
	Если ВызыватьСобытия
		И ПравилоВыгрузки <> Неопределено Тогда

		ИмяПКО = "";
		
		ВызватьСобытияПередВыгрузкойОбъекта(Объект, ПравилоВыгрузки, Свойства, ВходящиеДанные, 
			НеВыгружатьОбъектыСвойствПоСсылкам, ИмяПКО, Отказ, ИсходящиеДанные);
		
		Если Отказ Тогда
			Возврат Ложь;
		КонецЕсли;
		
	КонецЕсли;
	
	УзелСсылки = Неопределено;
	ВыгрузитьПоПравилу(Объект, , ВходящиеДанные, ИсходящиеДанные, ИмяПКО, УзелСсылки, , , НЕ НеВыгружатьОбъектыСвойствПоСсылкам, 
		ВыгрузкаСтрокиНабораЗаписей, УзелПредка, ИмяКонстантыДляВыгрузки, Истина);
		
		
	Если ВызыватьСобытия
		И ПравилоВыгрузки <> Неопределено Тогда
		
		ВызватьСобытияПослеВыгрузкиОбъекта(Объект, ПравилоВыгрузки, Свойства, ВходящиеДанные, 
		НеВыгружатьОбъектыСвойствПоСсылкам, ИмяПКО, Отказ, ИсходящиеДанные);	
		
	КонецЕсли;
	
	Возврат Не Отказ;
	
КонецФункции

// Возвращаемое значение:
//   ПостроительОтчета - объект построителя для выборки данных.
// 
Функция ОбъектПостроительОтчета()
	Если ПостроительОтчета = Неопределено Тогда
		ПостроительОтчета = Новый ПостроительОтчета;
	КонецЕсли;
	
	Возврат ПостроительОтчета;
КонецФункции

Функция ВыборкаДляВыгрузкиСОграничениями(Правило)
	
	ИмяМетаданных = Правило.ИмяОбъектаДляЗапроса;
	
	ТекстЗапроса = 
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	Объект.Ссылка КАК Ссылка
	|ИЗ
	|	&ИмяТаблицыМетаданных КАК Объект
	|{ГДЕ
	|	Объект.Ссылка.* КАК ПсевдонимДинамическогоУсловия}";
	
	Если НЕ ВыгружатьТолькоРазрешенные Тогда
		
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "РАЗРЕШЕННЫЕ", ""); // @Query-part-1
		
	КонецЕсли;
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяТаблицыМетаданных", ИмяМетаданных);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПсевдонимДинамическогоУсловия", СтрЗаменить(ИмяМетаданных, ".", "_"));
	
	ОбъектПостроительОтчета().Текст = ТекстЗапроса;
	ОбъектПостроительОтчета().Отбор.Сбросить();
	Если Не Правило.НастройкиПостроителя = Неопределено Тогда
		ОбъектПостроительОтчета().УстановитьНастройки(Правило.НастройкиПостроителя);
	КонецЕсли;

	ОбъектПостроительОтчета().Выполнить();
	Выборка = ОбъектПостроительОтчета().Результат.Выбрать();
		
	Возврат Выборка;
		
КонецФункции

Функция ВыборкаДляВыгрузкиПоПроизвольномуАлгоритму(ВыборкаДанных)
	
	Выборка = Неопределено;
	
	Если ТипЗнч(ВыборкаДанных) = Тип("ВыборкаИзРезультатаЗапроса") Тогда
		
		Выборка = ВыборкаДанных;
		
	ИначеЕсли ТипЗнч(ВыборкаДанных) = Тип("РезультатЗапроса") Тогда
		
		Выборка = ВыборкаДанных.Выбрать();
		
	ИначеЕсли ТипЗнч(ВыборкаДанных) = Тип("Запрос") Тогда
		
		РезультатЗапроса = ВыборкаДанных.Выполнить();
		Выборка          = РезультатЗапроса.Выбрать();
		
	КонецЕсли;
	
	Возврат Выборка;
	
КонецФункции

Функция СтрокаНабораКонстантДляВыгрузки(ТаблицаДанныхКонстантДляВыгрузки)
	
	СтрокаНабораКонстант = "";
	
	Для Каждого СтрокаТаблицы Из ТаблицаДанныхКонстантДляВыгрузки Цикл
		
		Если Не ПустаяСтрока(СтрокаТаблицы.Источник) Тогда
		
			СтрокаНабораКонстант = СтрокаНабораКонстант + ", " + СтрокаТаблицы.Источник;
			
		КонецЕсли;	
		
	КонецЦикла;	
	
	Если Не ПустаяСтрока(СтрокаНабораКонстант) Тогда
		
		СтрокаНабораКонстант = Сред(СтрокаНабораКонстант, 3);
		
	КонецЕсли;
	
	Возврат СтрокаНабораКонстант;
	
КонецФункции

Функция ВыгрузитьНаборКонстант(Правило, Свойства, ИсходящиеДанные, СтрокаИменНабораКонстант = "")
	
	Если СтрокаИменНабораКонстант = "" Тогда
		СтрокаИменНабораКонстант = СтрокаНабораКонстантДляВыгрузки(Свойства.ПКО.Свойства);
	КонецЕсли;
			
	НаборКонстант = Константы.СоздатьНабор(СтрокаИменНабораКонстант);
	НаборКонстант.Прочитать();
	РезультатВыгрузки = ВыгрузкаОбъектаВыборки(НаборКонстант, Правило, Свойства, ИсходящиеДанные, , , , СтрокаИменНабораКонстант);	
	Возврат РезультатВыгрузки;
	
КонецФункции

Функция ОпределитьНужноВыбиратьВсеПоля(Правило)
	
	НужныВсеПоляДляВыборки = НЕ ПустаяСтрока(Конвертация.ПередВыгрузкойОбъекта)
		ИЛИ НЕ ПустаяСтрока(Правило.ПередВыгрузкой)
		ИЛИ НЕ ПустаяСтрока(Конвертация.ПослеВыгрузкиОбъекта)
		ИЛИ НЕ ПустаяСтрока(Правило.ПослеВыгрузки);		
		
	Возврат НужныВсеПоляДляВыборки;	
	
КонецФункции

Процедура ОтработатьУдалениеОбъекта(ДанныеОбУдаленииОбъекта, СтрокаСообщенияОбОшибке = "")
	
	Ссылка = ДанныеОбУдаленииОбъекта.Ссылка;
	
	ТекстСобытия = "";
	Если Конвертация.Свойство("ПередОтправкойИнформацииОбУдалении", ТекстСобытия) Тогда
		
		Если Не ПустаяСтрока(ТекстСобытия) Тогда
			
			Отказ = Ложь;
			
			Попытка
				
				Если ОтладкаОбработчиковВыгрузки Тогда
					
					ВыполнитьОбработчик_Конвертация_ПередОтправкойИнформацииОбУдалении(Ссылка, Отказ);
					
				Иначе
					
					Выполнить(ТекстСобытия);
					
				КонецЕсли;
				
			Исключение
				СтрокаСообщенияОбОшибке = ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(76, 
					ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
					НСтр("ru = 'ПередОтправкойИнформацииОбУдалении (конвертация)'"));
				
				Если Не ПродолжитьПриОшибке Тогда
					ВызватьИсключение СтрокаСообщенияОбОшибке;
				КонецЕсли;
				
				Отказ = Истина;
			КонецПопытки;
			
			Если Отказ Тогда
				Возврат;
			КонецЕсли;
			
		КонецЕсли;
	КонецЕсли;
	
	Отбор = Новый Структура("Источник", ТипЗнч(Ссылка));
	ПравилаДляУдаления = КоллекцияПравилаКонвертации().Скопировать(Отбор, "ТипПриемника,ТипИсточника");
	ПравилаДляУдаления.Свернуть("ТипПриемника, ТипИсточника");
	
	Если ПравилаДляУдаления.Количество() = 0 Тогда

		ЗП = ЗаписьПротоколаОбмена(45);
		
		ЗП.Объект = Ссылка;
		ЗП.ТипОбъекта = ТипЗнч(Ссылка);
		
		ЗаписатьВПротоколВыполнения(45, ЗП, Истина);
		Возврат;
		
	КонецЕсли;
	
	Для Каждого ПКО Из ПравилаДляУдаления Цикл
		ЗаписатьВФайлУдалениеОбъекта(Ссылка, ПКО.ТипПриемника, ПКО.ТипИсточника);
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область ПроцедурыИФункцииКомпиляцииПравилОбменаВСтруктуру

// возвращает структуру правил обмена.
Функция ПравилаОбмена(Источник) Экспорт
	
	ЗагрузитьПравилаОбмена(Источник, "XMLФайл");
	
	Если ФлагОшибки() Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	// сохраняем запросы
	ЗапросыДляСохранения = Новый Структура;
	
	Для Каждого ЭлементСтруктуры Из Запросы Цикл
		
		ЗапросыДляСохранения.Вставить(ЭлементСтруктуры.Ключ, ЭлементСтруктуры.Значение.Текст);
		
	КонецЦикла;
	
	// сохраняем параметры
	ПараметрыДляСохранения = Новый Структура;
	
	Для Каждого ЭлементСтруктуры Из Параметры Цикл
		
		ПараметрыДляСохранения.Вставить(ЭлементСтруктуры.Ключ, Неопределено);
		
	КонецЦикла;
	
	СтруктураПравилОбмена = Новый Структура;
	
	СтруктураПравилОбмена.Вставить("ВерсияФорматаХраненияПравил", ВерсияФорматаХраненияПравилОбмена());
	
	СтруктураПравилОбмена.Вставить("Конвертация", Конвертация);
	
	СтруктураПравилОбмена.Вставить("ТаблицаНастройкиПараметров", ТаблицаНастройкиПараметров);
	СтруктураПравилОбмена.Вставить("ТаблицаПравилВыгрузки",      ТаблицаПравилВыгрузки);
	СтруктураПравилОбмена.Вставить("ТаблицаПравилКонвертации",   ТаблицаПравилКонвертации);
	
	СтруктураПравилОбмена.Вставить("Алгоритмы", Алгоритмы);
	СтруктураПравилОбмена.Вставить("Параметры", ПараметрыДляСохранения);
	СтруктураПравилОбмена.Вставить("Запросы",   ЗапросыДляСохранения);
	
	СтруктураПравилОбмена.Вставить("XMLПравила",              XMLПравила);
	СтруктураПравилОбмена.Вставить("СтрокаТиповДляПриемника", СтрокаТиповДляПриемника);
	
	// ПравилаВыборочнойРегистрацииОбъектов - далее хранятся в записях о правилах регистрации.
	
	Возврат СтруктураПравилОбмена;
	
КонецФункции

#КонецОбласти

#Область ИнициализацияТаблицПравилОбмена

// Инициализирует колонки таблицы правил конвертации свойств объектов.
//
// Параметры:
//  Таб - ТаблицаЗначений - инициализируемая таблица правил конвертации свойств.
// 
Процедура ИнициализацияТаблицыПравилКонвертацииСвойств(Таб)

	Колонки = Таб.Колонки;

	Колонки.Добавить("Имя");
	Колонки.Добавить("Наименование");
	Колонки.Добавить("Порядок");

	Колонки.Добавить("ЭтоГруппа",     одОписаниеТипа("Булево"));
	Колонки.Добавить("ЭтоПолеПоиска", одОписаниеТипа("Булево"));
	Колонки.Добавить("ПравилаГруппы");
	Колонки.Добавить("ПравилаГруппыОтключенные");

	Колонки.Добавить("ВидИсточника");
	Колонки.Добавить("ВидПриемника");
	
	Колонки.Добавить("УпрощеннаяВыгрузкаСвойства", одОписаниеТипа("Булево"));
	Колонки.Добавить("НуженУзелXMLПриВыгрузке", одОписаниеТипа("Булево"));
	Колонки.Добавить("НуженУзелXMLПриВыгрузкеГруппы", одОписаниеТипа("Булево"));

	Колонки.Добавить("ТипИсточника", одОписаниеТипа("Строка"));
	Колонки.Добавить("ТипПриемника", одОписаниеТипа("Строка"));
		
	Колонки.Добавить("Источник");
	Колонки.Добавить("Приемник");

	Колонки.Добавить("ПравилоКонвертации");

	Колонки.Добавить("ПолучитьИзВходящихДанных", одОписаниеТипа("Булево"));
	
	Колонки.Добавить("НеЗамещать",              одОписаниеТипа("Булево"));
	Колонки.Добавить("ЭтоОбязательноеСвойство", одОписаниеТипа("Булево"));
	
	Колонки.Добавить("ПередВыгрузкой");
	Колонки.Добавить("ИмяОбработчикаПередВыгрузкой");
	Колонки.Добавить("ПриВыгрузке");
	Колонки.Добавить("ИмяОбработчикаПриВыгрузке");
	Колонки.Добавить("ПослеВыгрузки");
	Колонки.Добавить("ИмяОбработчикаПослеВыгрузки");

	Колонки.Добавить("ПередОбработкойВыгрузки");
	Колонки.Добавить("ИмяОбработчикаПередОбработкойВыгрузки");
	Колонки.Добавить("ПослеОбработкиВыгрузки");
	Колонки.Добавить("ИмяОбработчикаПослеОбработкиВыгрузки");

	Колонки.Добавить("ЕстьОбработчикПередВыгрузкой",			одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПриВыгрузке",				одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПослеВыгрузки",				одОписаниеТипа("Булево"));
	
	Колонки.Добавить("ЕстьОбработчикПередОбработкойВыгрузки",	одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПослеОбработкиВыгрузки",	одОписаниеТипа("Булево"));
	
	Колонки.Добавить("ПриводитьКДлине",							одОписаниеТипа("Число"));
	Колонки.Добавить("ИмяПараметраДляПередачи", 				одОписаниеТипа("Строка"));
	Колонки.Добавить("ПоискПоДатеНаРавенство",					одОписаниеТипа("Булево"));
	Колонки.Добавить("ВыгружатьГруппуЧерезФайл",				одОписаниеТипа("Булево"));
	
	Колонки.Добавить("СтрокаПолейПоиска");
	
КонецПроцедуры

Функция СоздатьТаблицуВыгруженныхОбъектов()
	
	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить("Ключ");
	Таблица.Колонки.Добавить("УзелСсылки");
	Таблица.Колонки.Добавить("ВыгруженаТолькоСсылка",    Новый ОписаниеТипов("Булево"));
	Таблица.Колонки.Добавить("НППСсылки",                Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("КоличествоОбращений",      Новый ОписаниеТипов("Число"));
	Таблица.Колонки.Добавить("НомерПоследнегоОбращения", Новый ОписаниеТипов("Число"));
	
	Таблица.Индексы.Добавить("Ключ");
	
	Возврат Таблица;
	
КонецФункции

// Инициализирует колонки таблицы правил конвертации объектов.
// 
Процедура ИнициализацияТаблицыПравилКонвертации()

	Колонки = ТаблицаПравилКонвертации.Колонки;
	
	Колонки.Добавить("Имя");
	Колонки.Добавить("Наименование");
	Колонки.Добавить("Порядок");

	Колонки.Добавить("СинхронизироватьПоИдентификатору",                        одОписаниеТипа("Булево"));
	Колонки.Добавить("НеСоздаватьЕслиНеНайден",                                 одОписаниеТипа("Булево"));
	Колонки.Добавить("НеВыгружатьОбъектыСвойствПоСсылкам",                      одОписаниеТипа("Булево"));
	Колонки.Добавить("ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли", одОписаниеТипа("Булево"));
	Колонки.Добавить("ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD",       одОписаниеТипа("Булево"));
	Колонки.Добавить("НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике",   одОписаниеТипа("Булево"));
	Колонки.Добавить("ИспользоватьБыстрыйПоискПриЗагрузке",                     одОписаниеТипа("Булево"));
	Колонки.Добавить("ГенерироватьНовыйНомерИлиКодЕслиНеУказан",                одОписаниеТипа("Булево"));
	Колонки.Добавить("МаленькоеКоличествоОбъектов",                             одОписаниеТипа("Булево"));
	Колонки.Добавить("КоличествоОбращенийДляВыгрузкиСсылки",                    одОписаниеТипа("Число"));
	Колонки.Добавить("КоличествоЭлементовВИБ",                                  одОписаниеТипа("Число"));
	
	Колонки.Добавить("СпособВыгрузки");

	Колонки.Добавить("Источник");
	Колонки.Добавить("Приемник");
	
	Колонки.Добавить("ТипИсточника", одОписаниеТипа("Строка"));
	Колонки.Добавить("ТипПриемника", одОписаниеТипа("Строка"));
	
	Колонки.Добавить("ПередВыгрузкой");
	Колонки.Добавить("ИмяОбработчикаПередВыгрузкой");
	
	Колонки.Добавить("ПриВыгрузке");
	Колонки.Добавить("ИмяОбработчикаПриВыгрузке");
	
	Колонки.Добавить("ПослеВыгрузки");
	Колонки.Добавить("ИмяОбработчикаПослеВыгрузки");
	
	Колонки.Добавить("ПослеВыгрузкиВФайл");
	Колонки.Добавить("ИмяОбработчикаПослеВыгрузкиВФайл");

	Колонки.Добавить("ЕстьОбработчикПередВыгрузкой",	одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПриВыгрузке",		одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПослеВыгрузки",		одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПослеВыгрузкиВФайл",одОписаниеТипа("Булево"));

	Колонки.Добавить("ПередЗагрузкой");
	Колонки.Добавить("ИмяОбработчикаПередЗагрузкой");
	
	Колонки.Добавить("ПриЗагрузке");
	Колонки.Добавить("ИмяОбработчикаПриЗагрузке");
	
	Колонки.Добавить("ПослеЗагрузки");
	Колонки.Добавить("ИмяОбработчикаПослеЗагрузки");
	
	Колонки.Добавить("ПоследовательностьПолейПоиска");
	Колонки.Добавить("ИмяОбработчикаПоследовательностьПолейПоиска");

	Колонки.Добавить("ПоискПоТабличнымЧастям");
	
	Колонки.Добавить("ПриоритетОбъектовОбмена");
	
	Колонки.Добавить("ЕстьОбработчикПередЗагрузкой", одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПриЗагрузке",    одОписаниеТипа("Булево"));
	Колонки.Добавить("ЕстьОбработчикПослеЗагрузки",  одОписаниеТипа("Булево"));
	
	Колонки.Добавить("ЕстьОбработчикПоследовательностьПолейПоиска",  одОписаниеТипа("Булево"));

	Колонки.Добавить("Свойства",            одОписаниеТипа("ТаблицаЗначений"));
	Колонки.Добавить("СвойстваПоиска",      одОписаниеТипа("ТаблицаЗначений"));
	Колонки.Добавить("СвойстваОтключенные", одОписаниеТипа("ТаблицаЗначений"));
	
	// Свойство "Значения" не используется.
	// Колонки.Добавить("Значения", одОписаниеТипа("Соответствие"));
	
	// Соответствие.
	// Ключ - значение предопределенного элемента в этой базе;
	// Значение - строковое представление предопределенного значения в приемнике.
	Колонки.Добавить("ЗначенияПредопределенныхДанных", одОписаниеТипа("Соответствие"));
	
	// Структура.
	// Ключ - строковое представление предопределенного значения в этой базе;
	// Значение - строковое представление предопределенного значения в приемнике.
	Колонки.Добавить("ЗначенияПредопределенныхДанныхПрочитанные", одОписаниеТипа("Структура"));
	
	Колонки.Добавить("Выгруженные",                     одОписаниеТипа("ТаблицаЗначений"));
	Колонки.Добавить("ВыгружатьПредставлениеИсточника", одОписаниеТипа("Булево"));
	
	Колонки.Добавить("НеЗамещать",                  одОписаниеТипа("Булево"));
	
	Колонки.Добавить("ЗапоминатьВыгруженные",       одОписаниеТипа("Булево"));
	Колонки.Добавить("ВсеОбъектыВыгружены",         одОписаниеТипа("Булево"));
	
	Колонки.Добавить("ПоляПоиска",  одОписаниеТипа("Строка"));
	Колонки.Добавить("ПоляТаблицы", одОписаниеТипа("Строка"));
	
	Колонки.Добавить("ОбъектСДвижениями", одОписаниеТипа("Булево"));
	
КонецПроцедуры

// Инициализирует колонки таблицы правил выгрузки данных.
//
Процедура ИнициализацияТаблицыПравилВыгрузки()

	Колонки = ТаблицаПравилВыгрузки.Колонки;

	Колонки.Добавить("Включить", одОписаниеТипа("Булево"));
	
	Колонки.Добавить("Имя");
	Колонки.Добавить("Наименование");
	Колонки.Добавить("Порядок");

	Колонки.Добавить("СпособОтбораДанных");
	Колонки.Добавить("ОбъектВыборки");
	Колонки.Добавить("ОбъектВыборкиМетаданные");
	
	Колонки.Добавить("ПравилоКонвертации");

	Колонки.Добавить("ПередОбработкой");
	Колонки.Добавить("ИмяОбработчикаПередОбработкой");
	Колонки.Добавить("ПослеОбработки");
	Колонки.Добавить("ИмяОбработчикаПослеОбработки");

	Колонки.Добавить("ПередВыгрузкой");
	Колонки.Добавить("ИмяОбработчикаПередВыгрузкой");
	Колонки.Добавить("ПослеВыгрузки");
	Колонки.Добавить("ИмяОбработчикаПослеВыгрузки");
	
	// Колонки для поддержки отбора с помощью построителя.
	Колонки.Добавить("ИспользоватьОтбор", одОписаниеТипа("Булево"));
	Колонки.Добавить("НастройкиПостроителя");
	Колонки.Добавить("ИмяОбъектаДляЗапроса");
	Колонки.Добавить("ИмяОбъектаДляЗапросаРегистра");
	Колонки.Добавить("ИмяТипаПриемника");
	
	Колонки.Добавить("НеВыгружатьОбъектыСозданныеВБазеПриемнике", одОписаниеТипа("Булево"));
	
	Колонки.Добавить("СсылкаНаУзелОбмена");
	
	Колонки.Добавить("СинхронизироватьПоИдентификатору", одОписаниеТипа("Булево"));
	
КонецПроцедуры

// Инициализирует колонки таблицы правил очистки данных.
//
Процедура ИнициализацияТаблицыПравилОчистки()

	Колонки = ТаблицаПравилОчистки.Колонки;

	Колонки.Добавить("Включить",  одОписаниеТипа("Булево"));
	Колонки.Добавить("ЭтоГруппа", одОписаниеТипа("Булево"));
	
	Колонки.Добавить("Имя");
	Колонки.Добавить("Наименование");
	Колонки.Добавить("Порядок", одОписаниеТипа("Число"));

	Колонки.Добавить("СпособОтбораДанных");
	Колонки.Добавить("ОбъектВыборки");
	
	Колонки.Добавить("УдалятьЗаПериод");
	Колонки.Добавить("Непосредственно", одОписаниеТипа("Булево"));

	Колонки.Добавить("ПередОбработкой");
	Колонки.Добавить("ИмяОбработчикаПередОбработкой");
	Колонки.Добавить("ПослеОбработки");
	Колонки.Добавить("ИмяОбработчикаПослеОбработки");
	Колонки.Добавить("ПередУдалением");
	Колонки.Добавить("ИмяОбработчикаПередУдалением");

КонецПроцедуры

// Инициализирует колонки таблицы настройки параметров.
//
Процедура ИнициализацияТаблицыНастройкиПараметров()

	Колонки = ТаблицаНастройкиПараметров.Колонки;

	Колонки.Добавить("Имя");
	Колонки.Добавить("Наименование");
	Колонки.Добавить("Значение");
	Колонки.Добавить("ПередаватьПараметрПриВыгрузке");
	Колонки.Добавить("ПравилоКонвертации");

КонецПроцедуры

#КонецОбласти

#Область ИнициализацияРеквизитовИМодульныхПеременных

Функция ИнициализацияТаблицыДанныхСообщенияОбмена(ТипОбъекта)
	
	ТаблицаДанныхСообщенияОбмена = Новый ТаблицаЗначений;
	
	Колонки = ТаблицаДанныхСообщенияОбмена.Колонки;
	
	// обязательные поля
	Колонки.Добавить(ИмяКолонкиУникальныйИдентификатор(), ТипСтрока36);
	Колонки.Добавить(ИмяКолонкиТипСтрокой(),              ТипСтрока255);
	
	ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипОбъекта);
	
	// Получаем описание всех полей объекта метаданного из конфигурации.
	ТаблицаОписанияСвойствОбъекта = ОбщегоНазначения.ОписаниеСвойствОбъекта(ОбъектМетаданных, "Имя, Тип");
	
	Для Каждого ОписаниеСвойства Из ТаблицаОписанияСвойствОбъекта Цикл
		ТипыКолонки = Новый ОписаниеТипов(ОписаниеСвойства.Тип, "NULL");
		Колонки.Добавить(ОписаниеСвойства.Имя, ТипыКолонки);
	КонецЦикла;
	
	ТаблицаДанныхСообщенияОбмена.Индексы.Добавить(ИмяКолонкиУникальныйИдентификатор());
	
	Возврат ТаблицаДанныхСообщенияОбмена;
	
КонецФункции

Функция ИнициализироватьОбработки()
	
	Если ОтладкаОбработчиковВыгрузки Или ОтладкаОбработчиковЗагрузки Тогда 
		ВызватьИсключение
			НСтр("ru = 'Внешняя обработка отладки, загружаемая из файла на диске, не поддерживается.'");
	КонецЕсли;
	
	ИмяПланаОбмена = ИмяПланаОбмена();
	ИмяПрофиляБезопасности = ОбменДаннымиПовтИсп.ИмяПрофиляБезопасности(ИмяПланаОбмена);
	Возврат ИмяПрофиляБезопасности;
	
КонецФункции

// Отключает ранее подключенную для отладки обработку с кодом обработчиков.
//
Процедура ОтключитьОбработкуДляОтладки()
	
	Если ОбработкаВыгрузки <> Неопределено Тогда
		
		Попытка
			ОбработкаВыгрузки.ОтключитьОбработкуДляОтладки();
		Исключение
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Обмен данными'", ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецПопытки;
		ОбработкаВыгрузки = Неопределено;
		
	ИначеЕсли ОбработкаЗагрузки <> Неопределено Тогда
		
		Попытка
			ОбработкаЗагрузки.ОтключитьОбработкуДляОтладки();
		Исключение
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Обмен данными'", ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецПопытки;
		
		ОбработкаЗагрузки = Неопределено;
		
	КонецЕсли;
	
КонецПроцедуры

// Инициализирует переменную СообщенияОбОшибках, содержащую соответствия кодов сообщений их описаниям.
//
// Параметры:
//  Нет.
// 
Процедура ИнициализацияСообщений()

	СообщенияОбОшибках			= Новый Соответствие;
		
	СообщенияОбОшибках.Вставить(2,  НСтр("ru = 'Ошибка распаковки файла обмена. Файл заблокирован.'"));
	СообщенияОбОшибках.Вставить(3,  НСтр("ru = 'Указанный файл правил обмена не существует.'"));
	СообщенияОбОшибках.Вставить(4,  НСтр("ru = 'Ошибка при создании COM-объекта Msxml2.DOMDocument'"));
	СообщенияОбОшибках.Вставить(5,  НСтр("ru = 'Ошибка открытия файла обмена'"));
	СообщенияОбОшибках.Вставить(6,  НСтр("ru = 'Ошибка при загрузке правил обмена'"));
	СообщенияОбОшибках.Вставить(7,  НСтр("ru = 'Ошибка формата правил обмена'"));
	СообщенияОбОшибках.Вставить(8,  НСтр("ru = 'Некорректно указано имя файла для выгрузки данных'")); // не используется
	СообщенияОбОшибках.Вставить(9,  НСтр("ru = 'Ошибка формата файла обмена'"));
	СообщенияОбОшибках.Вставить(10, НСтр("ru = 'Не указано имя файла для выгрузки данных (Имя файла данных)'"));
	СообщенияОбОшибках.Вставить(11, НСтр("ru = 'Ссылка на несуществующий объект метаданных в правилах обмена'"));
	СообщенияОбОшибках.Вставить(12, НСтр("ru = 'Не указано имя файла с правилами обмена (Имя файла правил)'"));
			
	СообщенияОбОшибках.Вставить(13, НСтр("ru = 'Ошибка получения значения свойства объекта (по имени свойства источника)'"));
	СообщенияОбОшибках.Вставить(14, НСтр("ru = 'Ошибка получения значения свойства объекта (по имени свойства приемника)'"));
	
	СообщенияОбОшибках.Вставить(15, НСтр("ru = 'Не указано имя файла для загрузки данных (Имя файла для загрузки)'"));
			
	СообщенияОбОшибках.Вставить(16, НСтр("ru = 'Ошибка получения значения свойства подчиненного объекта (по имени свойства источника)'"));
	СообщенияОбОшибках.Вставить(17, НСтр("ru = 'Ошибка получения значения свойства подчиненного объекта (по имени свойства приемника)'"));
	СообщенияОбОшибках.Вставить(18, НСтр("ru = 'Ошибка при создании обработки с кодом обработчиков'"));
	СообщенияОбОшибках.Вставить(19, НСтр("ru = 'Ошибка в обработчике события ПередЗагрузкойОбъекта'"));
	СообщенияОбОшибках.Вставить(20, НСтр("ru = 'Ошибка в обработчике события ПриЗагрузкеОбъекта'"));
	СообщенияОбОшибках.Вставить(21, НСтр("ru = 'Ошибка в обработчике события ПослеЗагрузкиОбъекта'"));
	СообщенияОбОшибках.Вставить(22, НСтр("ru = 'Ошибка в обработчике события ПередЗагрузкойДанных (конвертация)'"));
	СообщенияОбОшибках.Вставить(23, НСтр("ru = 'Ошибка в обработчике события ПослеЗагрузкиДанных (конвертация)'"));
	СообщенияОбОшибках.Вставить(24, НСтр("ru = 'Ошибка при удалении объекта'"));
	СообщенияОбОшибках.Вставить(25, НСтр("ru = 'Ошибка при записи документа'"));
	СообщенияОбОшибках.Вставить(26, НСтр("ru = 'Ошибка записи объекта'"));
	СообщенияОбОшибках.Вставить(27, НСтр("ru = 'Ошибка в обработчике события ПередОбработкойПравилаОчистки'"));
	СообщенияОбОшибках.Вставить(28, НСтр("ru = 'Ошибка в обработчике события ПослеОбработкиПравилаОчистки'"));
	СообщенияОбОшибках.Вставить(29, НСтр("ru = 'Ошибка в обработчике события ПередУдалениемОбъекта'"));
	
	СообщенияОбОшибках.Вставить(31, НСтр("ru = 'Ошибка в обработчике события ПередОбработкойПравилаВыгрузки'"));
	СообщенияОбОшибках.Вставить(32, НСтр("ru = 'Ошибка в обработчике события ПослеОбработкиПравилаВыгрузки'"));
	СообщенияОбОшибках.Вставить(33, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкойОбъекта'"));
	СообщенияОбОшибках.Вставить(34, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиОбъекта'"));
			
	СообщенияОбОшибках.Вставить(41, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкойОбъекта'"));
	СообщенияОбОшибках.Вставить(42, НСтр("ru = 'Ошибка в обработчике события ПриВыгрузкеОбъекта'"));
	СообщенияОбОшибках.Вставить(43, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиОбъекта'"));
			
	СообщенияОбОшибках.Вставить(45, НСтр("ru = 'Не найдено правило конвертации объектов'"));
		
	СообщенияОбОшибках.Вставить(48, НСтр("ru = 'Ошибка в обработчике события ПередОбработкойВыгрузки группы свойств'"));
	СообщенияОбОшибках.Вставить(49, НСтр("ru = 'Ошибка в обработчике события ПослеОбработкиВыгрузки группы свойств'"));
	СообщенияОбОшибках.Вставить(50, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкой (объекта коллекции)'"));
	СообщенияОбОшибках.Вставить(51, НСтр("ru = 'Ошибка в обработчике события ПриВыгрузке (объекта коллекции)'"));
	СообщенияОбОшибках.Вставить(52, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузки (объекта коллекции)'"));
	СообщенияОбОшибках.Вставить(53, НСтр("ru = 'Ошибка в глобальном обработчике события ПередЗагрузкойОбъекта (конвертация)'"));
	СообщенияОбОшибках.Вставить(54, НСтр("ru = 'Ошибка в глобальном обработчике события ПослеЗагрузкиОбъекта (конвертация)'"));
	СообщенияОбОшибках.Вставить(55, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкой (свойства)'"));
	СообщенияОбОшибках.Вставить(56, НСтр("ru = 'Ошибка в обработчике события ПриВыгрузке (свойства)'"));
	СообщенияОбОшибках.Вставить(57, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузки (свойства)'"));
	
	СообщенияОбОшибках.Вставить(62, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкойДанных (конвертация)'"));
	СообщенияОбОшибках.Вставить(63, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиДанных (конвертация)'"));
	СообщенияОбОшибках.Вставить(64, НСтр("ru = 'Ошибка в глобальном обработчике события ПередКонвертациейОбъекта (конвертация)'"));
	СообщенияОбОшибках.Вставить(65, НСтр("ru = 'Ошибка в глобальном обработчике события ПередВыгрузкойОбъекта (конвертация)'"));
	СообщенияОбОшибках.Вставить(66, НСтр("ru = 'Ошибка получения коллекции подчиненных объектов из входящих данных'"));
	СообщенияОбОшибках.Вставить(67, НСтр("ru = 'Ошибка получения свойства подчиненного объекта из входящих данных'"));
	СообщенияОбОшибках.Вставить(68, НСтр("ru = 'Ошибка получения свойства объекта из входящих данных'"));
	
	СообщенияОбОшибках.Вставить(69, НСтр("ru = 'Ошибка в глобальном обработчике события ПослеВыгрузкиОбъекта (конвертация)'"));
	
	СообщенияОбОшибках.Вставить(71, НСтр("ru = 'Не найдено соответствие для значения Источника'"));
	
	СообщенияОбОшибках.Вставить(72, НСтр("ru = 'Ошибка при выгрузке данных для узла плана обмена'"));
	
	СообщенияОбОшибках.Вставить(73, НСтр("ru = 'Ошибка в обработчике события ПоследовательностьПолейПоиска'"));
	СообщенияОбОшибках.Вставить(74, НСтр("ru = 'Перезагрузите правила обмена для выгрузки данных.'"));
	
	СообщенияОбОшибках.Вставить(75, НСтр("ru = 'Ошибка в обработчике события ПослеЗагрузкиПравилОбмена (конвертация)'"));
	СообщенияОбОшибках.Вставить(76, НСтр("ru = 'Ошибка в обработчике события ПередОтправкойИнформацииОбУдалении (конвертация)'"));
	СообщенияОбОшибках.Вставить(77, НСтр("ru = 'Ошибка в обработчике события ПриПолученииИнформацииОбУдалении (конвертация)'"));
	
	СообщенияОбОшибках.Вставить(78, НСтр("ru = 'Ошибка при выполнении алгоритма после загрузки значений параметров'"));
	
	СообщенияОбОшибках.Вставить(79, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиОбъектаВФайл'"));
	
	СообщенияОбОшибках.Вставить(80, НСтр("ru = 'Ошибка установки свойства предопределенного элемента.
		|Нельзя помечать на удаление предопределенный элемент. Пометка на удаление для объекта не установлена.'"));
	//
	СообщенияОбОшибках.Вставить(83, НСтр("ru = 'Ошибка обращения к табличной части объекта. Табличная часть объекта не может быть изменена.'"));
	СообщенияОбОшибках.Вставить(84, НСтр("ru = 'Коллизия дат запрета изменения.'"));
	
	СообщенияОбОшибках.Вставить(173, НСтр("ru = 'Ошибка блокировки узла обмена. Возможно синхронизация данных уже выполняется'"));
	СообщенияОбОшибках.Вставить(174, НСтр("ru = 'Сообщение обмена было принято ранее'"));
	СообщенияОбОшибках.Вставить(175, НСтр("ru = 'Ошибка в обработчике события ПередПолучениемИзмененныхОбъектов (конвертация)'"));
	СообщенияОбОшибках.Вставить(176, НСтр("ru = 'Ошибка в обработчике события ПослеПолученияИнформацииОбУзлахОбмена (конвертация)'"));
		
	СообщенияОбОшибках.Вставить(1000, НСтр("ru = 'Ошибка при создании временного файла выгрузки данных'"));
		
КонецПроцедуры

Процедура ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, ИмяТипа, Менеджер, ПрефиксИмениТипа, ВозможенПоискПоПредопределенным = Ложь)
	
	Имя              = ОбъектМД.Имя;
	ТипСсылкиСтрокой = ПрефиксИмениТипа + "." + Имя;
	
	ТекстЗапросаПоиска = "ВЫБРАТЬ Ссылка ИЗ &ИмяТаблицыМетаданных";
	ТекстЗапросаПоиска = СтрЗаменить(ТекстЗапросаПоиска, "&ИмяТаблицыМетаданных", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1.%2", ИмяТипа, Имя));
	СтрокаПоиска = ТекстЗапросаПоиска + " ГДЕ ";
	
	ТекстЗапросаВыгрузки = "ВЫБРАТЬ &ПоляПоискаПараметр ИЗ &ИмяТаблицыМетаданных";
	ТекстЗапросаВыгрузки = СтрЗаменить(ТекстЗапросаВыгрузки, "&ИмяТаблицыМетаданных", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1.%2", ИмяТипа, Имя));
	СтрокаПоискаВыгрузкиСсылки     = СтрЗаменить(ТекстЗапросаВыгрузки, "&ПоляПоискаПараметр", "#ПоляПоиска#");
	
	ТипСсылки        = Тип(ТипСсылкиСтрокой);
	
	Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД);
	Структура.Вставить("СтрокаПоиска",СтрокаПоиска);
	Структура.Вставить("СтрокаПоискаВыгрузкиСсылки",СтрокаПоискаВыгрузкиСсылки);
	Структура.Вставить("ВозможенПоискПоПредопределенным",ВозможенПоискПоПредопределенным);

	Менеджеры.Вставить(ТипСсылки, Структура);
	
	
	СтруктураДляПланаОбмена = СтруктураПараметровПланаОбмена(Имя, ТипСсылки, Истина, Ложь);

	МенеджерыДляПлановОбмена.Вставить(ОбъектМД, СтруктураДляПланаОбмена);
	
КонецПроцедуры

Процедура ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, ИмяТипа, Менеджер, ПрефиксИмениТипаЗапись, ПрефиксИмениТипаВыборка)
	
	Периодический = Неопределено;
	
	Имя					= ОбъектМД.Имя;
	ТипСсылкиСтрокой	= ПрефиксИмениТипаЗапись + "." + Имя;
	ТипСсылки			= Тип(ТипСсылкиСтрокой);
	Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД);

	Если ИмяТипа = "РегистрСведений" Тогда
		
		Периодический = (ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический);
		ПодчиненныйРегистратору = (ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору);
		
		Структура.Вставить("Периодический", Периодический);
		Структура.Вставить("ПодчиненныйРегистратору", ПодчиненныйРегистратору);
		
	КонецЕсли;	
	
	Менеджеры.Вставить(ТипСсылки, Структура);
		
	СтруктураДляПланаОбмена = СтруктураПараметровПланаОбмена(Имя, ТипСсылки, Ложь, Истина);

	МенеджерыДляПлановОбмена.Вставить(ОбъектМД, СтруктураДляПланаОбмена);
	
	
	ТипСсылкиСтрокой	= ПрефиксИмениТипаВыборка + "." + Имя;
	ТипСсылки			= Тип(ТипСсылкиСтрокой);
	Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД);

	Если Периодический <> Неопределено Тогда
		
		Структура.Вставить("Периодический", Периодический);
		Структура.Вставить("ПодчиненныйРегистратору", ПодчиненныйРегистратору);
		
	КонецЕсли;
	
	Менеджеры.Вставить(ТипСсылки, Структура);
		
КонецПроцедуры

// Инициализирует переменную Менеджеры, содержащую соответствия типов объектов их свойствам.
//
// Параметры:
//  Нет.
// 
Процедура ИнициализацияМенеджеров()

	Менеджеры = Новый Соответствие;
	
	МенеджерыДляПлановОбмена = Новый Соответствие;
    	
	// ССЫЛКИ
	
	Для каждого ОбъектМД Из Метаданные.Справочники Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "Справочник", Справочники[ОбъектМД.Имя], "СправочникСсылка", Истина);
					
	КонецЦикла;

	Для каждого ОбъектМД Из Метаданные.Документы Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "Документ", Документы[ОбъектМД.Имя], "ДокументСсылка");
				
	КонецЦикла;

	Для каждого ОбъектМД Из Метаданные.ПланыВидовХарактеристик Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланВидовХарактеристик", ПланыВидовХарактеристик[ОбъектМД.Имя], "ПланВидовХарактеристикСсылка", Истина);
				
	КонецЦикла;
	
	Для каждого ОбъектМД Из Метаданные.ПланыСчетов Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланСчетов", ПланыСчетов[ОбъектМД.Имя], "ПланСчетовСсылка", Истина);
						
	КонецЦикла;
	
	Для каждого ОбъектМД Из Метаданные.ПланыВидовРасчета Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланВидовРасчета", ПланыВидовРасчета[ОбъектМД.Имя], "ПланВидовРасчетаСсылка", Истина);
				
	КонецЦикла;
	
	Для каждого ОбъектМД Из Метаданные.ПланыОбмена Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланОбмена", ПланыОбмена[ОбъектМД.Имя], "ПланОбменаСсылка");
				
	КонецЦикла;
	
	Для каждого ОбъектМД Из Метаданные.Задачи Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "Задача", Задачи[ОбъектМД.Имя], "ЗадачаСсылка");
				
	КонецЦикла;
	
	Для каждого ОбъектМД Из Метаданные.БизнесПроцессы Цикл
		
		ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "БизнесПроцесс", БизнесПроцессы[ОбъектМД.Имя], "БизнесПроцессСсылка");
		
		ИмяТипа = "ТочкаМаршрутаБизнесПроцесса";
		// ссылка на точки маршрута
		Имя              = ОбъектМД.Имя;
		Менеджер         = БизнесПроцессы[Имя].ТочкиМаршрута;
		СтрокаПоиска     = "";
		ТипСсылкиСтрокой = "ТочкаМаршрутаБизнесПроцессаСсылка." + Имя;
		ТипСсылки        = Тип(ТипСсылкиСтрокой);
		Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД);
		Структура.Вставить("ПустаяСсылка", Неопределено);
		Структура.Вставить("СтрокаПоиска", СтрокаПоиска);

		Менеджеры.Вставить(ТипСсылки, Структура);
				
	КонецЦикла;
	
	// РЕГИСТРЫ

	Для каждого ОбъектМД Из Метаданные.РегистрыСведений Цикл
		
		ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрСведений", РегистрыСведений[ОбъектМД.Имя], "РегистрСведенийЗапись", "РегистрСведенийВыборка");
						
	КонецЦикла;

	Для каждого ОбъектМД Из Метаданные.РегистрыБухгалтерии Цикл
		
		ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрБухгалтерии", РегистрыБухгалтерии[ОбъектМД.Имя], "РегистрБухгалтерииЗапись", "РегистрБухгалтерииВыборка");
				
	КонецЦикла;
	
	Для каждого ОбъектМД Из Метаданные.РегистрыНакопления Цикл
		
		ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрНакопления", РегистрыНакопления[ОбъектМД.Имя], "РегистрНакопленияЗапись", "РегистрНакопленияВыборка");
						
	КонецЦикла;
	
	Для каждого ОбъектМД Из Метаданные.РегистрыРасчета Цикл
		
		ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрРасчета", РегистрыРасчета[ОбъектМД.Имя], "РегистрРасчетаЗапись", "РегистрРасчетаВыборка");
						
	КонецЦикла;
	
	ИмяТипа = "Перечисление";
	
	Для каждого ОбъектМД Из Метаданные.Перечисления Цикл
		
		Имя              = ОбъектМД.Имя;
		Менеджер         = Перечисления[Имя];
		ТипСсылкиСтрокой = "ПеречислениеСсылка." + Имя;
		ТипСсылки        = Тип(ТипСсылкиСтрокой);
		Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД);
		Структура.Вставить("ПустаяСсылка", Перечисления[Имя].ПустаяСсылка());

		Менеджеры.Вставить(ТипСсылки, Структура);
		
	КонецЦикла;
	
	// Константы
	ИмяТипа             = "Константы";
	ОбъектМД            = Метаданные.Константы;
	Имя					= "Константы";
	Менеджер			= Константы;
	ТипСсылкиСтрокой	= "КонстантыНабор";
	ТипСсылки			= Тип(ТипСсылкиСтрокой);
	Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД);

	Менеджеры.Вставить(ТипСсылки, Структура);
	
КонецПроцедуры

Процедура ИнициализироватьМенеджерыИСообщения()
	
	Если Менеджеры = Неопределено Тогда
		ИнициализацияМенеджеров();
	КонецЕсли; 

	Если СообщенияОбОшибках = Неопределено Тогда
		ИнициализацияСообщений();
	КонецЕсли;
	
КонецПроцедуры

// Возвращаемое значение:
//   Структура:
//     * ВерсияФормата - Строка
//     * Ид - Строка
//     * Наименование - Строка
//     * ДатаВремяСоздания - Дата
//     * ВерсияПлатформыИсточника - Строка
//     * СинонимКонфигурацииИсточника - Строка
//     * ВерсияКонфигурацииИсточника - Строка
//     * Источник - Строка
//     * ВерсияПлатформыПриемника - Строка
//     * СинонимКонфигурацииПриемника - Строка
//     * ВерсияКонфигурацииПриемника - Строка
//     * Приемник - Строка
//     * ПослеЗагрузкиПравилОбмена - Строка
//     * ИмяОбработчикаПослеЗагрузкиПравилОбмена - Строка
//     * ПередВыгрузкойДанных - Строка
//     * ИмяОбработчикаПередВыгрузкойДанных - Строка
//     * ПередПолучениемИзмененныхОбъектов - Строка
//     * ИмяОбработчикаПередПолучениемИзмененныхОбъектов - Строка
//     * ПослеПолученияИнформацииОбУзлахОбмена - Строка
//     * ИмяОбработчикаПослеПолученияИнформацииОбУзлахОбмена - Строка
//     * ПослеВыгрузкиДанных - Строка
//     * ИмяОбработчикаПослеВыгрузкиДанных - Строка
//     * ПередОтправкойИнформацииОбУдалении - Строка
//     * ИмяОбработчикаПередОтправкойИнформацииОбУдалении - Строка
//     * ПередВыгрузкойОбъекта - Строка
//     * ИмяОбработчикаПередВыгрузкойОбъекта - Строка
//     * ПослеВыгрузкиОбъекта - Строка
//     * ИмяОбработчикаПослеВыгрузкиОбъекта - Строка
//     * ПередЗагрузкойОбъекта - Строка
//     * ИмяОбработчикаПередЗагрузкойОбъекта - Строка
//     * ПослеЗагрузкиОбъекта - Строка
//     * ИмяОбработчикаПослеЗагрузкиОбъекта - Строка
//     * ПередКонвертациейОбъекта - Строка
//     * ИмяОбработчикаПередКонвертациейОбъекта - Строка
//     * ПередЗагрузкойДанных - Строка
//     * ИмяОбработчикаПередЗагрузкойДанных - Строка
//     * ПослеЗагрузкиДанных - Строка
//     * ИмяОбработчикаПослеЗагрузкиДанных - Строка
//     * ПослеЗагрузкиПараметров - Строка
//     * ИмяОбработчикаПослеЗагрузкиПараметров - Строка
//     * ПриПолученииИнформацииОбУдалении - Строка
//     * ИмяОбработчикаПриПолученииИнформацииОбУдалении - Строка
//     * УдалятьСопоставленныеОбъектыВПриемникеПриИхУдаленииВИсточнике - Булево
//
Функция Конвертация()
	Возврат Конвертация;
КонецФункции

// Возвращаемое значение:
//   Структура:
//     * Имя - Строка
//     * ИмяТипа - Строка
//     * ТипСсылкиСтрокой - Строка
//     * Менеджер - СправочникМенеджер
//                - ДокументМенеджер
//                - РегистрСведенийМенеджер
//                - и т.п.
//     * ОбъектМД - ОбъектМетаданныхСправочник
//                - ОбъектМетаданныхДокумент
//                - ОбъектМетаданныхРегистрСведений
//                - и т.п.
//     * ПКО - СтрокаТаблицыЗначений - строка таблицы правил конвертации:
//       ** Свойства - см. КоллекцияПравилаКонвертацииСвойств
//
Функция Менеджеры(Тип)
	Возврат Менеджеры[Тип];
КонецФункции

Процедура СоздатьСтруктуруКонвертации()
	
	Конвертация = Новый Структура("ПередВыгрузкойДанных, ПослеВыгрузкиДанных, ПередПолучениемИзмененныхОбъектов, ПослеПолученияИнформацииОбУзлахОбмена, ПередВыгрузкойОбъекта, ПослеВыгрузкиОбъекта, ПередКонвертациейОбъекта, ПередЗагрузкойОбъекта, ПослеЗагрузкиОбъекта, ПередЗагрузкойДанных, ПослеЗагрузкиДанных, ПриПолученииИнформацииОбУдалении, ПередОтправкойИнформацииОбУдалении");
	Конвертация.Вставить("УдалятьСопоставленныеОбъектыВПриемникеПриИхУдаленииВИсточнике", Ложь);
	Конвертация.Вставить("ВерсияФормата");
	Конвертация.Вставить("ДатаВремяСоздания");
		
КонецПроцедуры

// Инициализирует реквизиты обработки и модульные переменные.
//
Процедура ИнициализацияРеквизитовИМодульныхПеременных()

	РежимВизуальнойНастройкиОбмена = Ложь;
	КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 100;
	
	ЧислоХранимыхВыгруженныхОбъектовПоТипам = 2000;
		
	ПараметрыИнициализированы        = Ложь;
	
	Менеджеры    = Неопределено;
	СообщенияОбОшибках  = Неопределено;
	
	УстановитьФлагОшибки(Ложь);
	
	СоздатьСтруктуруКонвертации();
	
	Правила      = Новый Структура;
	Алгоритмы    = Новый Структура;
	ДопОбработки = Новый Структура;
	Запросы      = Новый Структура;

	Параметры    = Новый Структура;
	СобытияПослеЗагрузкиПараметров = Новый Структура;
	
	ПараметрыДопОбработок = Новый Структура;
    	
	XMLПравила  = Неопределено;
	
	// Типы

	ТипСтрока                  = Тип("Строка");
	ТипБулево                  = Тип("Булево");
	ТипЧисло                   = Тип("Число");
	ТипДата                    = Тип("Дата");
	ТипХранилищеЗначения       = Тип("ХранилищеЗначения");
	ТипУникальныйИдентификатор = Тип("УникальныйИдентификатор");
	ТипДвоичныеДанные          = Тип("ДвоичныеДанные");
	ТипВидДвиженияНакопления   = Тип("ВидДвиженияНакопления");
	ТипУдалениеОбъекта         = Тип("УдалениеОбъекта");
	ТипВидСчета			       = Тип("ВидСчета");
	ТипТип                     = Тип("Тип");
	ТипСоответствие            = Тип("Соответствие");
	ТипОписаниеТипов           = Тип("ОписаниеТипов");
	
	ТипСтрока36  = Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(36));
	ТипСтрока255 = Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(255));
	
	ТипРегистрСоответствия    = Тип("РегистрСведенийНаборЗаписей.СоответствияОбъектовИнформационныхБаз");

	ЗначениеПустаяДата		   = Дата('00010101');
	
	КоличествоОбъектовКЗагрузке     = 0;
	КоличествоОбъектовКВыгрузке     = 0;
	РазмерФайлаСообщенияОбмена      = 0;

	// Типы узлов xml
	
	ТипУзлаXMLКонецЭлемента  = ТипУзлаXML.КонецЭлемента;
	ТипУзлаXMLНачалоЭлемента = ТипУзлаXML.НачалоЭлемента;
	ТипУзлаXMLТекст          = ТипУзлаXML.Текст;
	
	ФайлПротоколаДанных = Неопределено;
	
	СоответствиеТиповИНазваниеОбъектов = Новый Соответствие();
	
	СоответствиеПустыхЗначенийТипов = Новый Соответствие;
	СоответствиеОписаниеТипов = Новый Соответствие;
	
	РазрешитьПроведениеДокумента = Метаданные.СвойстваОбъектов.Проведение.Разрешить;
	
	РежимЗагрузкиИнформацииОПравилахОбмена = Ложь;
	
	ПолеРезультатВыполненияОбмена = Неопределено;
	
	ИнформацияОПользовательскихПоляхПоискаПриВыгрузкеДанных = Новый Соответствие();
	ИнформацияОПользовательскихПоляхПоискаПриЗагрузкеДанных = Новый Соответствие();
		
	МенеджерРегистраСоответствийОбъектов = РегистрыСведений.СоответствияОбъектовИнформационныхБаз;
	
	// Запрос для определения информации о сопоставлении объектов для подмены ссылки источника, на ссылку приемника.
	ЗапросСоответствияОбъектовИнформационныхБаз = Новый Запрос;
	ЗапросСоответствияОбъектовИнформационныхБаз.Текст = "
	|ВЫБРАТЬ ПЕРВЫЕ 1
	|	СоответствияОбъектовИнформационныхБаз.УникальныйИдентификаторИсточникаСтрокой КАК УникальныйИдентификаторИсточникаСтрокой
	|ИЗ
	|	РегистрСведений.СоответствияОбъектовИнформационныхБаз КАК СоответствияОбъектовИнформационныхБаз
	|ГДЕ
	|	  СоответствияОбъектовИнформационныхБаз.УзелИнформационнойБазы           = &УзелИнформационнойБазы
	|	И СоответствияОбъектовИнформационныхБаз.УникальныйИдентификаторПриемника = &УникальныйИдентификаторПриемника
	|	И СоответствияОбъектовИнформационныхБаз.ТипПриемника                     = &ТипПриемника
	|	И СоответствияОбъектовИнформационныхБаз.ТипИсточника                     = &ТипИсточника
	|";
	//
	
КонецПроцедуры

Процедура УстановитьФлагОшибки(Значение = Истина)
	
	ПолеФлагОшибки = Значение;
	
КонецПроцедуры

Процедура Инкремент(Значение, Знач Итератор = 1)
	
	Если ТипЗнч(Значение) <> Тип("Число") Тогда
		
		Значение = 0;
		
	КонецЕсли;
	
	Значение = Значение + Итератор;
	
КонецПроцедуры

Процедура ЗафиксироватьЗавершениеЗагрузкиДанных()
	
	СостояниеОбменаДанными().РезультатВыполненияОбмена = РезультатВыполненияОбмена();
	СостояниеОбменаДанными().ДействиеПриОбмене         = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
	СостояниеОбменаДанными().УзелИнформационнойБазы    = УзелОбменаЗагрузкаДанных;
	
	РегистрыСведений.СостоянияОбменовДанными.ДобавитьЗапись(СостояниеОбменаДанными());
	
	// Фиксируем успешное выполнение обмена в РС.
	Если РезультатВыполненияОбмена() = Перечисления.РезультатыВыполненияОбмена.Выполнено Тогда
		
		// Создаем и заполняем структуру для новой записи в РС.
		СтруктураЗаписи = Новый Структура("УзелИнформационнойБазы, ДействиеПриОбмене, ДатаОкончания");
		ЗаполнитьЗначенияСвойств(СтруктураЗаписи, СостояниеОбменаДанными());
		
		РегистрыСведений.СостоянияУспешныхОбменовДанными.ДобавитьЗапись(СтруктураЗаписи);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура УвеличитьСчетчикЗагруженныхОбъектов()
	
	Если ЗагрузкаДанныхВыполняетсяЧерезВнешнееСоединение Тогда
		Если СчетчикЗагруженныхОбъектовВнешнееСоединение > 0 Тогда
			ПолеСчетчикЗагруженныхОбъектов = СчетчикЗагруженныхОбъектовВнешнееСоединение;
		ИначеЕсли КоличествоОбъектовКЗагрузкеВнешнееСоединение > СчетчикЗагруженныхОбъектов() Тогда
			Инкремент(ПолеСчетчикЗагруженныхОбъектов);
		КонецЕсли;
	Иначе
		Инкремент(ПолеСчетчикЗагруженныхОбъектов);
	КонецЕсли;
	
КонецПроцедуры

Функция СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД)
	Структура = Новый Структура();
	Структура.Вставить("Имя", Имя);
	Структура.Вставить("ИмяТипа", ИмяТипа);
	Структура.Вставить("ТипСсылкиСтрокой", ТипСсылкиСтрокой);
	Структура.Вставить("Менеджер", Менеджер);
	Структура.Вставить("ОбъектМД", ОбъектМД);
	Структура.Вставить("ВозможенПоискПоПредопределенным", Ложь);
	Структура.Вставить("ПКО");
	Возврат Структура;
КонецФункции

Функция СтруктураПараметровПланаОбмена(Имя, ТипСсылки, ЭтоСсылочныйТип, ЭтоРегистр)
	Структура = Новый Структура();
	Структура.Вставить("Имя",Имя);
	Структура.Вставить("ТипСсылки",ТипСсылки);
	Структура.Вставить("ЭтоСсылочныйТип",ЭтоСсылочныйТип);
	Структура.Вставить("ЭтоРегистр",ЭтоРегистр);
	Возврат Структура;
КонецФункции

#КонецОбласти

#Область ПроцедурыОбработчиков

Функция ИмяСвойстваПКС(СтрокаТабличнойЧасти)
	
	Если ЗначениеЗаполнено(СтрокаТабличнойЧасти.Источник) Тогда
		Свойство = "_" + СокрЛП(СтрокаТабличнойЧасти.Источник);
	ИначеЕсли ЗначениеЗаполнено(СтрокаТабличнойЧасти.Приемник) Тогда 
		Свойство = "_" + СокрЛП(СтрокаТабличнойЧасти.Приемник);
	ИначеЕсли ЗначениеЗаполнено(СтрокаТабличнойЧасти.ИмяПараметраДляПередачи) Тогда
		Свойство = "_" + СокрЛП(СтрокаТабличнойЧасти.ИмяПараметраДляПередачи);
	Иначе
		Свойство = "";
	КонецЕсли;
	
	Возврат Свойство;
	
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Глобальные обработчики

Процедура ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиПравилОбмена()
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПослеЗагрузкиПравилОбмена);
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПередВыгрузкойДанных(ФайлОбмена, Отказ)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПередВыгрузкойДанных, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПередПолучениемИзмененныхОбъектов(Получатель, УзелДляФоновогоОбмена)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Получатель);
	ПараметрыОбработчика.Добавить(УзелДляФоновогоОбмена);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПередПолучениемИзмененныхОбъектов, ПараметрыОбработчика);
	
	Получатель = ПараметрыОбработчика[0];
	УзелДляФоновогоОбмена = ПараметрыОбработчика[1];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПослеВыгрузкиДанных(ФайлОбмена)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПослеВыгрузкиДанных, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПередВыгрузкойОбъекта(ФайлОбмена, Отказ, ИмяПКО, Правило,
																ВходящиеДанные, ИсходящиеДанные, Объект)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(Объект);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПередВыгрузкойОбъекта, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	ИмяПКО = ПараметрыОбработчика[2];
	Правило = ПараметрыОбработчика[3];
	ВходящиеДанные = ПараметрыОбработчика[4];
	ИсходящиеДанные = ПараметрыОбработчика[5];
	Объект = ПараметрыОбработчика[6];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПослеВыгрузкиОбъекта(ФайлОбмена, Объект, ИмяПКО, ВходящиеДанные,
															   ИсходящиеДанные, УзелСсылки)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Объект);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(УзелСсылки);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПослеВыгрузкиОбъекта, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Объект = ПараметрыОбработчика[1];
	ИмяПКО = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	УзелСсылки = ПараметрыОбработчика[5];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПередКонвертациейОбъекта(ПараметрыОбработчика)
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПередКонвертациейОбъекта, ПараметрыОбработчика);
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПередОтправкойИнформацииОбУдалении(Ссылка, Отказ)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Ссылка);
	ПараметрыОбработчика.Добавить(Отказ);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Конвертация.ИмяОбработчикаПередОтправкойИнформацииОбУдалении, ПараметрыОбработчика);
	
	Ссылка = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПередЗагрузкойДанных(ФайлОбмена, Отказ)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Конвертация.ИмяОбработчикаПередЗагрузкойДанных, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиДанных()
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Конвертация.ИмяОбработчикаПослеЗагрузкиДанных);
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПередЗагрузкойОбъекта(ФайлОбмена, Отказ, НПП, Источник, ИмяПравила, Правило,
																ГенерироватьНовыйНомерИлиКодЕслиНеУказан,ТипОбъектаСтрокой,
																ТипОбъекта, НеЗамещатьОбъект, РежимЗаписи, РежимПроведения)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(НПП);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(ИмяПравила);
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(ГенерироватьНовыйНомерИлиКодЕслиНеУказан);
	ПараметрыОбработчика.Добавить(ТипОбъектаСтрокой);
	ПараметрыОбработчика.Добавить(ТипОбъекта);
	ПараметрыОбработчика.Добавить(НеЗамещатьОбъект);
	ПараметрыОбработчика.Добавить(РежимЗаписи);
	ПараметрыОбработчика.Добавить(РежимПроведения);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Конвертация.ИмяОбработчикаПередЗагрузкойОбъекта, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	НПП = ПараметрыОбработчика[2];
	Источник = ПараметрыОбработчика[3];
	ИмяПравила = ПараметрыОбработчика[4];
	Правило = ПараметрыОбработчика[5];
	ГенерироватьНовыйНомерИлиКодЕслиНеУказан = ПараметрыОбработчика[6];
	ТипОбъектаСтрокой = ПараметрыОбработчика[7];
	ТипОбъекта = ПараметрыОбработчика[8];
	НеЗамещатьОбъект = ПараметрыОбработчика[9];
	РежимЗаписи = ПараметрыОбработчика[10];
	РежимПроведения = ПараметрыОбработчика[11];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиОбъекта(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта,
															   ОбъектМодифицирован, ИмяТипаОбъекта, ОбъектНайден)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(Ссылка);
	ПараметрыОбработчика.Добавить(Объект);
	ПараметрыОбработчика.Добавить(ПараметрыОбъекта);
	ПараметрыОбработчика.Добавить(ОбъектМодифицирован);
	ПараметрыОбработчика.Добавить(ИмяТипаОбъекта);
	ПараметрыОбработчика.Добавить(ОбъектНайден);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Конвертация.ИмяОбработчикаПослеЗагрузкиОбъекта, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	Ссылка = ПараметрыОбработчика[2];
	Объект = ПараметрыОбработчика[3];
	ПараметрыОбъекта = ПараметрыОбработчика[4];
	ОбъектМодифицирован = ПараметрыОбработчика[5];
	ИмяТипаОбъекта = ПараметрыОбработчика[6];
	ОбъектНайден = ПараметрыОбработчика[7];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПриПолученииИнформацииОбУдалении(Объект, Отказ)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Объект);
	ПараметрыОбработчика.Добавить(Отказ);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Конвертация.ИмяОбработчикаПриПолученииИнформацииОбУдалении, ПараметрыОбработчика);
	
	Объект = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиПараметров(ФайлОбмена, Отказ, ПричинаОтказа)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(ПричинаОтказа);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, "Конвертация_ПослеЗагрузкиПараметров", ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	ПричинаОтказа = ПараметрыОбработчика[2];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_Конвертация_ПослеПолученияИнформацииОбУзлахОбмена(Знач УзелОбменаЗагрузкаДанных)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(УзелОбменаЗагрузкаДанных);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Конвертация.ИмяОбработчикаПослеПолученияИнформацииОбУзлахОбмена, ПараметрыОбработчика);
	
	УзелОбменаЗагрузкаДанных = ПараметрыОбработчика[0];
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики ПКО

Процедура ВыполнитьОбработчик_ПКО_ПередВыгрузкойОбъекта(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные,
														ИмяПКО, ПКО, ВыгруженныеОбъекты, Отказ, КлючВыгружаемыхДанных,
														ЗапоминатьВыгруженные, НеЗамещатьОбъектПриЗагрузке,
														ВсеОбъектыВыгружены, ТолькоПолучитьУзелСсылки, Приемник,
														РежимЗаписи, РежимПроведения, НеСоздаватьЕслиНеНайден)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ВыгруженныеОбъекты);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(КлючВыгружаемыхДанных);
	ПараметрыОбработчика.Добавить(ЗапоминатьВыгруженные);
	ПараметрыОбработчика.Добавить(НеЗамещатьОбъектПриЗагрузке);
	ПараметрыОбработчика.Добавить(ВсеОбъектыВыгружены);
	ПараметрыОбработчика.Добавить(ТолькоПолучитьУзелСсылки);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(РежимЗаписи);
	ПараметрыОбработчика.Добавить(РежимПроведения);
	ПараметрыОбработчика.Добавить(НеСоздаватьЕслиНеНайден);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКО.ИмяОбработчикаПередВыгрузкой, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	ВходящиеДанные = ПараметрыОбработчика[2];
	ИсходящиеДанные = ПараметрыОбработчика[3];
	ИмяПКО = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ВыгруженныеОбъекты = ПараметрыОбработчика[6];
	Отказ = ПараметрыОбработчика[7];
	КлючВыгружаемыхДанных = ПараметрыОбработчика[8];
	ЗапоминатьВыгруженные = ПараметрыОбработчика[9];
	НеЗамещатьОбъектПриЗагрузке = ПараметрыОбработчика[10];
	ВсеОбъектыВыгружены = ПараметрыОбработчика[11];
	ТолькоПолучитьУзелСсылки = ПараметрыОбработчика[12];
	Приемник = ПараметрыОбработчика[13];
	РежимЗаписи = ПараметрыОбработчика[14];
	РежимПроведения = ПараметрыОбработчика[15];
	НеСоздаватьЕслиНеНайден = ПараметрыОбработчика[16];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКО_ПриВыгрузкеОбъекта(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО, ПКО,
													 ВыгруженныеОбъекты, КлючВыгружаемыхДанных, Отказ, СтандартнаяОбработка,
													 Приемник, УзелСсылки)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ВыгруженныеОбъекты);
	ПараметрыОбработчика.Добавить(КлючВыгружаемыхДанных);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(СтандартнаяОбработка);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(УзелСсылки);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКО.ИмяОбработчикаПриВыгрузке, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	ВходящиеДанные = ПараметрыОбработчика[2];
	ИсходящиеДанные = ПараметрыОбработчика[3];
	ИмяПКО = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ВыгруженныеОбъекты = ПараметрыОбработчика[6];
	КлючВыгружаемыхДанных = ПараметрыОбработчика[7];
	Отказ = ПараметрыОбработчика[8];
	СтандартнаяОбработка = ПараметрыОбработчика[9];
	Приемник = ПараметрыОбработчика[10];
	УзелСсылки = ПараметрыОбработчика[11];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКО_ПослеВыгрузкиОбъекта(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО, ПКО,
													   ВыгруженныеОбъекты, КлючВыгружаемыхДанных, Отказ, Приемник, УзелСсылки)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ВыгруженныеОбъекты);
	ПараметрыОбработчика.Добавить(КлючВыгружаемыхДанных);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(УзелСсылки);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКО.ИмяОбработчикаПослеВыгрузки, ПараметрыОбработчика);
		
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	ВходящиеДанные = ПараметрыОбработчика[2];
	ИсходящиеДанные = ПараметрыОбработчика[3];
	ИмяПКО = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ВыгруженныеОбъекты = ПараметрыОбработчика[6];
	КлючВыгружаемыхДанных = ПараметрыОбработчика[7];
	Отказ = ПараметрыОбработчика[8];
	Приемник = ПараметрыОбработчика[9];
	УзелСсылки = ПараметрыОбработчика[10];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКО_ПослеВыгрузкиОбъектаВФайлОбмена(ФайлОбмена, Источник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО, ПКО,
																  ВыгруженныеОбъекты, Приемник, УзелСсылки)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ВыгруженныеОбъекты);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(УзелСсылки);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКО.ИмяОбработчикаПослеВыгрузкиВФайл, ПараметрыОбработчика);
		
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	ВходящиеДанные = ПараметрыОбработчика[2];
	ИсходящиеДанные = ПараметрыОбработчика[3];
	ИмяПКО = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ВыгруженныеОбъекты = ПараметрыОбработчика[6];
	Приемник = ПараметрыОбработчика[7];
	УзелСсылки = ПараметрыОбработчика[8];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКО_ПередЗагрузкойОбъекта(ФайлОбмена, Отказ, НПП, Источник, ИмяПравила, Правило,
														ГенерироватьНовыйНомерИлиКодЕслиНеУказан, ТипОбъектаСтрокой,
														ТипОбъекта,НеЗамещатьОбъект, РежимЗаписи, РежимПроведения)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(НПП);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(ИмяПравила);
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(ГенерироватьНовыйНомерИлиКодЕслиНеУказан);
	ПараметрыОбработчика.Добавить(ТипОбъектаСтрокой);
	ПараметрыОбработчика.Добавить(ТипОбъекта);
	ПараметрыОбработчика.Добавить(НеЗамещатьОбъект);
	ПараметрыОбработчика.Добавить(РежимЗаписи);
	ПараметрыОбработчика.Добавить(РежимПроведения);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Правило.ИмяОбработчикаПередЗагрузкой, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	НПП = ПараметрыОбработчика[2];
	Источник = ПараметрыОбработчика[3];
	ИмяПравила = ПараметрыОбработчика[4];
	Правило = ПараметрыОбработчика[5];
	ГенерироватьНовыйНомерИлиКодЕслиНеУказан = ПараметрыОбработчика[6];
	ТипОбъектаСтрокой = ПараметрыОбработчика[7];
	ТипОбъекта = ПараметрыОбработчика[8];
	НеЗамещатьОбъект = ПараметрыОбработчика[9];
	РежимЗаписи = ПараметрыОбработчика[10];
	РежимПроведения = ПараметрыОбработчика[11];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКО_ПриЗагрузкеОбъекта(ФайлОбмена, ОбъектНайден, Объект, НеЗамещатьОбъект, ОбъектМодифицирован, Правило)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(ОбъектНайден);
	ПараметрыОбработчика.Добавить(Объект);
	ПараметрыОбработчика.Добавить(НеЗамещатьОбъект);
	ПараметрыОбработчика.Добавить(ОбъектМодифицирован);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Правило.ИмяОбработчикаПриЗагрузке, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	ОбъектНайден = ПараметрыОбработчика[1];
	Объект = ПараметрыОбработчика[2];
	НеЗамещатьОбъект = ПараметрыОбработчика[3];
	ОбъектМодифицирован = ПараметрыОбработчика[4];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКО_ПослеЗагрузкиОбъекта(ФайлОбмена, Отказ, Ссылка, Объект, ПараметрыОбъекта,
													   ОбъектМодифицирован, ИмяТипаОбъекта, ОбъектНайден, Правило)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(Ссылка);
	ПараметрыОбработчика.Добавить(Объект);
	ПараметрыОбработчика.Добавить(ПараметрыОбъекта);
	ПараметрыОбработчика.Добавить(ОбъектМодифицирован);
	ПараметрыОбработчика.Добавить(ИмяТипаОбъекта);
	ПараметрыОбработчика.Добавить(ОбъектНайден);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Правило.ИмяОбработчикаПослеЗагрузки, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	Ссылка = ПараметрыОбработчика[2];
	Объект = ПараметрыОбработчика[3];
	ПараметрыОбъекта = ПараметрыОбработчика[4];
	ОбъектМодифицирован = ПараметрыОбработчика[5];
	ИмяТипаОбъекта = ПараметрыОбработчика[6];
	ОбъектНайден = ПараметрыОбработчика[7];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКО_ПоследовательностьПолейПоиска(НомерВариантаПоиска, СвойстваПоиска, ПараметрыОбъекта, ПрекратитьПоиск,
																СсылкаНаОбъект, УстанавливатьУОбъектаВсеСвойстваПоиска,
																СтрокаИменСвойствПоиска, ИмяОбработчика)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(НомерВариантаПоиска);
	ПараметрыОбработчика.Добавить(СвойстваПоиска);
	ПараметрыОбработчика.Добавить(ПараметрыОбъекта);
	ПараметрыОбработчика.Добавить(ПрекратитьПоиск);
	ПараметрыОбработчика.Добавить(СсылкаНаОбъект);
	ПараметрыОбработчика.Добавить(УстанавливатьУОбъектаВсеСвойстваПоиска);
	ПараметрыОбработчика.Добавить(СтрокаИменСвойствПоиска);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, ИмяОбработчика, ПараметрыОбработчика);
		
	НомерВариантаПоиска = ПараметрыОбработчика[0];
	СвойстваПоиска = ПараметрыОбработчика[1];
	ПараметрыОбъекта = ПараметрыОбработчика[2];
	ПрекратитьПоиск = ПараметрыОбработчика[3];
	СсылкаНаОбъект = ПараметрыОбработчика[4];
	УстанавливатьУОбъектаВсеСвойстваПоиска = ПараметрыОбработчика[5];
	СтрокаИменСвойствПоиска = ПараметрыОбработчика[6];
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики ПКС

Процедура ВыполнитьОбработчик_ПКС_ПередВыгрузкойСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
														 ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, ТипПриемника, ИмяПКО,
														 ИмяПКОВидСубконто, Пусто, Выражение, УзелКоллекцииСвойств, НеЗамещать,
														 ВыгрузитьОбъект)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКС);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ОбъектКоллекции);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(Значение);
	ПараметрыОбработчика.Добавить(ТипПриемника);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ИмяПКОВидСубконто);
	ПараметрыОбработчика.Добавить(Пусто);
	ПараметрыОбработчика.Добавить(Выражение);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(НеЗамещать);
	ПараметрыОбработчика.Добавить(ВыгрузитьОбъект);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКС.ИмяОбработчикаПередВыгрузкой, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКС = ПараметрыОбработчика[5];
	ПКО = ПараметрыОбработчика[6];
	ОбъектКоллекции = ПараметрыОбработчика[7];
	Отказ = ПараметрыОбработчика[8];
	Значение = ПараметрыОбработчика[9];
	ТипПриемника = ПараметрыОбработчика[10];
	ИмяПКО = ПараметрыОбработчика[11];
	ИмяПКОВидСубконто = ПараметрыОбработчика[12];
	Пусто = ПараметрыОбработчика[13];
	Выражение = ПараметрыОбработчика[14];
	УзелКоллекцииСвойств = ПараметрыОбработчика[15];
	НеЗамещать = ПараметрыОбработчика[16];
	ВыгрузитьОбъект = ПараметрыОбработчика[17];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКС_ПриВыгрузкеСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
													  ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, КлючИЗначение, ВидСубконто,
													  Субконто, Пусто, ИмяПКО, ПКОСвойств,УзелСвойства, УзелКоллекцииСвойств,
													  ИмяПКОВидСубконто, ВыгрузитьОбъект)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКС);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ОбъектКоллекции);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(Значение);
	ПараметрыОбработчика.Добавить(КлючИЗначение);
	ПараметрыОбработчика.Добавить(ВидСубконто);
	ПараметрыОбработчика.Добавить(Субконто);
	ПараметрыОбработчика.Добавить(Пусто);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ПКОСвойств);
	ПараметрыОбработчика.Добавить(УзелСвойства);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(ИмяПКОВидСубконто);
	ПараметрыОбработчика.Добавить(ВыгрузитьОбъект);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКС.ИмяОбработчикаПриВыгрузке, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКС = ПараметрыОбработчика[5];
	ПКО = ПараметрыОбработчика[6];
	ОбъектКоллекции = ПараметрыОбработчика[7];
	Отказ = ПараметрыОбработчика[8];
	Значение = ПараметрыОбработчика[9];
	КлючИЗначение = ПараметрыОбработчика[10];
	ВидСубконто = ПараметрыОбработчика[11];
	Субконто = ПараметрыОбработчика[12];
	Пусто = ПараметрыОбработчика[13];
	ИмяПКО = ПараметрыОбработчика[14];
	ПКОСвойств = ПараметрыОбработчика[15];
	УзелСвойства = ПараметрыОбработчика[16];
	УзелКоллекцииСвойств = ПараметрыОбработчика[17];
	ИмяПКОВидСубконто = ПараметрыОбработчика[18];
	ВыгрузитьОбъект = ПараметрыОбработчика[19];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКС_ПослеВыгрузкиСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
														ПКС, ПКО, ОбъектКоллекции, Отказ, Значение, КлючИЗначение, ВидСубконто,
														Субконто, ИмяПКО, ИмяПКОВидСубконто, ПКОСвойств, УзелСвойства,
														УзелСсылки, УзелКоллекцииСвойств, УзелСубконто)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКС);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ОбъектКоллекции);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(Значение);
	ПараметрыОбработчика.Добавить(КлючИЗначение);
	ПараметрыОбработчика.Добавить(ВидСубконто);
	ПараметрыОбработчика.Добавить(Субконто);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ИмяПКОВидСубконто);
	ПараметрыОбработчика.Добавить(ПКОСвойств);
	ПараметрыОбработчика.Добавить(УзелСвойства);
	ПараметрыОбработчика.Добавить(УзелСсылки);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(УзелСубконто);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКС.ИмяОбработчикаПослеВыгрузки, ПараметрыОбработчика);
		
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКС = ПараметрыОбработчика[5];
	ПКО = ПараметрыОбработчика[6];
	ОбъектКоллекции = ПараметрыОбработчика[7];
	Отказ = ПараметрыОбработчика[8];
	Значение = ПараметрыОбработчика[9];
	КлючИЗначение = ПараметрыОбработчика[10];
	ВидСубконто = ПараметрыОбработчика[11];
	Субконто = ПараметрыОбработчика[12];
	ИмяПКО = ПараметрыОбработчика[13];
	ИмяПКОВидСубконто = ПараметрыОбработчика[14];
	ПКОСвойств = ПараметрыОбработчика[15];
	УзелСвойства = ПараметрыОбработчика[16];
	УзелСсылки = ПараметрыОбработчика[17];
	УзелКоллекцииСвойств = ПараметрыОбработчика[18];
	УзелСубконто = ПараметрыОбработчика[19];
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики ПКГС

Процедура ВыполнитьОбработчик_ПКГС_ПередОбработкойВыгрузки(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО,
														   ПКГС, Отказ, КоллекцияОбъектов, НеЗамещать, УзелКоллекцииСвойств, НеОчищать)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ПКГС);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(КоллекцияОбъектов);
	ПараметрыОбработчика.Добавить(НеЗамещать);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(НеОчищать);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКГС.ИмяОбработчикаПередОбработкойВыгрузки, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ПКГС = ПараметрыОбработчика[6];
	Отказ = ПараметрыОбработчика[7];
	КоллекцияОбъектов = ПараметрыОбработчика[8];
	НеЗамещать = ПараметрыОбработчика[9];
	УзелКоллекцииСвойств = ПараметрыОбработчика[10];
	НеОчищать = ПараметрыОбработчика[11];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКГС_ПередВыгрузкойСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО,
														  ПКГС, Отказ, ОбъектКоллекции, УзелКоллекцииСвойств, УзелКоллекцииОбъектов)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ПКГС);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(ОбъектКоллекции);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(УзелКоллекцииОбъектов);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКГС.ИмяОбработчикаПередВыгрузкой, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ПКГС = ПараметрыОбработчика[6];
	Отказ = ПараметрыОбработчика[7];
	ОбъектКоллекции = ПараметрыОбработчика[8];
	УзелКоллекцииСвойств = ПараметрыОбработчика[9];
	УзелКоллекцииОбъектов = ПараметрыОбработчика[10];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКГС_ПриВыгрузкеСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО,
													   ПКГС, ОбъектКоллекции, УзелКоллекцииОбъектов, УзелОбъектаКоллекции,
													   УзелКоллекцииСвойств, СтандартнаяОбработка)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ПКГС);
	ПараметрыОбработчика.Добавить(ОбъектКоллекции);
	ПараметрыОбработчика.Добавить(УзелКоллекцииОбъектов);
	ПараметрыОбработчика.Добавить(УзелОбъектаКоллекции);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(СтандартнаяОбработка);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКГС.ИмяОбработчикаПриВыгрузке, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ПКГС = ПараметрыОбработчика[6];
	ОбъектКоллекции = ПараметрыОбработчика[7];
	УзелКоллекцииОбъектов = ПараметрыОбработчика[8];
	УзелОбъектаКоллекции = ПараметрыОбработчика[9];
	УзелКоллекцииСвойств = ПараметрыОбработчика[10];
	СтандартнаяОбработка = ПараметрыОбработчика[11];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКГС_ПослеВыгрузкиСвойства(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
														 ПКО, ПКГС, Отказ, ОбъектКоллекции, УзелКоллекцииОбъектов,
														 УзелКоллекцииСвойств, УзелОбъектаКоллекции)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ПКГС);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(ОбъектКоллекции);
	ПараметрыОбработчика.Добавить(УзелКоллекцииОбъектов);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(УзелОбъектаКоллекции);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКГС.ИмяОбработчикаПослеВыгрузки, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ПКГС = ПараметрыОбработчика[6];
	Отказ = ПараметрыОбработчика[7];
	ОбъектКоллекции = ПараметрыОбработчика[8];
	УзелКоллекцииОбъектов = ПараметрыОбработчика[9];
	УзелКоллекцииСвойств = ПараметрыОбработчика[10];
	УзелОбъектаКоллекции = ПараметрыОбработчика[11];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПКГС_ПослеОбработкиВыгрузки(ФайлОбмена, Источник, Приемник, ВходящиеДанные, ИсходящиеДанные,
														  ПКО, ПКГС, Отказ, УзелКоллекцииСвойств, УзелКоллекцииОбъектов)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Источник);
	ПараметрыОбработчика.Добавить(Приемник);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ПКО);
	ПараметрыОбработчика.Добавить(ПКГС);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(УзелКоллекцииСвойств);
	ПараметрыОбработчика.Добавить(УзелКоллекцииОбъектов);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, ПКГС.ИмяОбработчикаПослеОбработкиВыгрузки, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Источник = ПараметрыОбработчика[1];
	Приемник = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	ПКО = ПараметрыОбработчика[5];
	ПКГС = ПараметрыОбработчика[6];
	Отказ = ПараметрыОбработчика[7];
	УзелКоллекцииСвойств = ПараметрыОбработчика[8];
	УзелКоллекцииОбъектов = ПараметрыОбработчика[9];
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики ПВД

Процедура ВыполнитьОбработчик_ПВД_ПередОбработкойПравила(Отказ, ИмяПКО, Правило, ИсходящиеДанные, ВыборкаДанных)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ВыборкаДанных);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Правило.ИмяОбработчикаПередОбработкой, ПараметрыОбработчика);
	
	Отказ = ПараметрыОбработчика[0];
	ИмяПКО = ПараметрыОбработчика[1];
	Правило = ПараметрыОбработчика[2];
	ИсходящиеДанные = ПараметрыОбработчика[3];
	ВыборкаДанных = ПараметрыОбработчика[4];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПВД_ПослеОбработкиПравила(ИмяПКО, Правило, ИсходящиеДанные)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Правило.ИмяОбработчикаПослеОбработки, ПараметрыОбработчика);
	
	ИмяПКО = ПараметрыОбработчика[0];
	Правило = ПараметрыОбработчика[1];
	ИсходящиеДанные = ПараметрыОбработчика[2];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПВД_ПередВыгрузкойОбъекта(ФайлОбмена, Отказ, ИмяПКО, Правило,
														ВходящиеДанные, ИсходящиеДанные, Объект)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(Объект);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Правило.ИмяОбработчикаПередВыгрузкой, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	ИмяПКО = ПараметрыОбработчика[2];
	Правило = ПараметрыОбработчика[3];
	ВходящиеДанные = ПараметрыОбработчика[4];
	ИсходящиеДанные = ПараметрыОбработчика[5];
	Объект = ПараметрыОбработчика[6];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПВД_ПослеВыгрузкиОбъекта(ФайлОбмена, Объект, ИмяПКО, ВходящиеДанные,
													   ИсходящиеДанные, УзелСсылки, Правило)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(ФайлОбмена);
	ПараметрыОбработчика.Добавить(Объект);
	ПараметрыОбработчика.Добавить(ИмяПКО);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(УзелСсылки);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаВыгрузки, Правило.ИмяОбработчикаПослеВыгрузки, ПараметрыОбработчика);
	
	ФайлОбмена = ПараметрыОбработчика[0];
	Объект = ПараметрыОбработчика[1];
	ИмяПКО = ПараметрыОбработчика[2];
	ВходящиеДанные = ПараметрыОбработчика[3];
	ИсходящиеДанные = ПараметрыОбработчика[4];
	УзелСсылки = ПараметрыОбработчика[5];
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики ПОД

Процедура ВыполнитьОбработчик_ПОД_ПередОбработкойПравила(Правило, Отказ, ИсходящиеДанные, ВыборкаДанных)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(ИсходящиеДанные);
	ПараметрыОбработчика.Добавить(ВыборкаДанных);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Правило.ИмяОбработчикаПередОбработкой, ПараметрыОбработчика);
	
	Правило = ПараметрыОбработчика[0];
	Отказ = ПараметрыОбработчика[1];
	ИсходящиеДанные = ПараметрыОбработчика[2];
	ВыборкаДанных = ПараметрыОбработчика[3];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПОД_ПередУдалениемОбъекта(Правило, Объект, Отказ, УдалитьНепосредственно, ВходящиеДанные)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Правило);
	ПараметрыОбработчика.Добавить(Объект);
	ПараметрыОбработчика.Добавить(Отказ);
	ПараметрыОбработчика.Добавить(УдалитьНепосредственно);
	ПараметрыОбработчика.Добавить(ВходящиеДанные);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Правило.ИмяОбработчикаПередУдалением, ПараметрыОбработчика);
	
	Правило = ПараметрыОбработчика[0];
	Объект = ПараметрыОбработчика[1];
	Отказ = ПараметрыОбработчика[2];
	УдалитьНепосредственно = ПараметрыОбработчика[3];
	ВходящиеДанные = ПараметрыОбработчика[4];
	
КонецПроцедуры

Процедура ВыполнитьОбработчик_ПОД_ПослеОбработкиПравила(Правило)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Правило);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, Правило.ИмяОбработчикаПослеОбработки, ПараметрыОбработчика);
	
	Правило = ПараметрыОбработчика[0];
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики Параметров

Процедура ВыполнитьОбработчик_Параметры_ПослеЗагрузкиПараметра(Имя, Значение)
	
	ПараметрыОбработчика = Новый Массив();
	ПараметрыОбработчика.Добавить(Имя);
	ПараметрыОбработчика.Добавить(Значение);
	
	ИмяОбработчика = "Параметры_[ИмяПараметра]_ПослеЗагрузкиПараметра";
	ИмяОбработчика = СтрЗаменить(ИмяОбработчика, "[ИмяПараметра]", Имя);
	
	ОбщегоНазначения.ВыполнитьМетодОбъекта(
		ОбработкаЗагрузки, ИмяОбработчика, ПараметрыОбработчика);
	
	Имя = ПараметрыОбработчика[0];
	Значение = ПараметрыОбработчика[1];
	
КонецПроцедуры

#КонецОбласти

#Область Константы

Функция ВерсияФорматаСообщенияОбмена()
	
	Возврат "3.1";
	
КонецФункции

// Версия формата хранения правил обмена (формат зачитанных правил),
// работу с которой поддерживает данная обработка.
//
// Правила обмена зачитываются из файла и сохраняются в информационной базе в формате хранения.
// Формат хранения правил может устаревать. В этом случае потребуется перечитать правила обмена повторно.
//
Функция ВерсияФорматаХраненияПравилОбмена()
	
	Возврат 2;
	
КонецФункции

#КонецОбласти

#Область Прочее

Процедура ПолучитьЗначенияПредопределенныхДанных(Знач ПКО)
	
	ПКО.ЗначенияПредопределенныхДанных = Новый Соответствие;
	
	Для Каждого Элемент Из ПКО.ЗначенияПредопределенныхДанныхПрочитанные Цикл
		
		ПКО.ЗначенияПредопределенныхДанных.Вставить(одПолучитьЗначениеПоСтроке(Элемент.Ключ, ПКО.Источник), Элемент.Значение);
		
	КонецЦикла;
	
КонецПроцедуры

Функция ПредставлениеКонфигурацииИзПравилОбмена(ИмяОпределения)
	
	ИмяКонфигурации = "";
	Конвертация.Свойство("СинонимКонфигурации" + ИмяОпределения, ИмяКонфигурации);
	
	Если Не ЗначениеЗаполнено(ИмяКонфигурации) Тогда
		Возврат "";
	КонецЕсли;
	
	ТочнаяВерсия = "";
	Конвертация.Свойство("ВерсияКонфигурации" + ИмяОпределения, ТочнаяВерсия);
	
	Если ЗначениеЗаполнено(ТочнаяВерсия) Тогда
		
		ТочнаяВерсия = ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(ТочнаяВерсия);
		
		ИмяКонфигурации = ИмяКонфигурации + " версия " + ТочнаяВерсия;
		
	КонецЕсли;
	
	Возврат ИмяКонфигурации;
	
КонецФункции

Процедура ЗаполнитьСвойстваДляПоиска(СтруктураДанных, ПКС)
	
	Для Каждого СтрокаПолей Из ПКС Цикл
		
		Если СтрокаПолей.ЭтоГруппа Тогда
						
			Если СтрокаПолей.ВидПриемника = "ТабличнаяЧасть" 
				ИЛИ СтрНайти(СтрокаПолей.ВидПриемника, "НаборДвижений") > 0 Тогда
				
				ИмяСтруктурыПриемника = СтрокаПолей.Приемник + ?(СтрокаПолей.ВидПриемника = "ТабличнаяЧасть", "ТабличнаяЧасть", "НаборЗаписей");
				
				ВнутренняяСтруктура = СтруктураДанных[ИмяСтруктурыПриемника];
				
				Если ВнутренняяСтруктура = Неопределено Тогда
					ВнутренняяСтруктура = Новый Соответствие();
				КонецЕсли;
				
				СтруктураДанных[ИмяСтруктурыПриемника] = ВнутренняяСтруктура;
				
			Иначе
				
				ВнутренняяСтруктура = СтруктураДанных;	
				
			КонецЕсли;
			
			ЗаполнитьСвойстваДляПоиска(ВнутренняяСтруктура, СтрокаПолей.ПравилаГруппы);
									
		Иначе
			
			Если ПустаяСтрока(СтрокаПолей.ТипПриемника)	Тогда
				
				Продолжить;
				
			КонецЕсли;
			
			СтруктураДанных[СтрокаПолей.Приемник] = СтрокаПолей.ТипПриемника;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура УдалитьЛишниеЭлементыИзСоответствия(СтруктураДанных)
	
	МассивКлючейДляУдаления = Новый Массив;
	
	Для Каждого Элемент Из СтруктураДанных Цикл
		
		Если ТипЗнч(Элемент.Значение) = ТипСоответствие Тогда
			
			УдалитьЛишниеЭлементыИзСоответствия(Элемент.Значение);
			
			Если Элемент.Значение.Количество() = 0 Тогда
				МассивКлючейДляУдаления.Добавить(Элемент.Ключ);
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Для Каждого Ключ Из МассивКлючейДляУдаления Цикл
		СтруктураДанных.Удалить(Ключ);
	КонецЦикла;	
	
КонецПроцедуры

Процедура ЗаполнитьИнформациюПоТипамДанныхПриемника(СтруктураДанных, Правила)
	
	Для Каждого Строка Из Правила Цикл
		
		Если ПустаяСтрока(Строка.Приемник) Тогда
			Продолжить;
		КонецЕсли;
		
		ДанныеСтруктуры = СтруктураДанных[Строка.Приемник];
		Если ДанныеСтруктуры = Неопределено Тогда
			
			ДанныеСтруктуры = Новый Соответствие();
			СтруктураДанных[Строка.Приемник] = ДанныеСтруктуры;
			
		КонецЕсли;
		
		// Бежим по полям поиск и прочим ПКС и запоминаем типы данных.
		ЗаполнитьСвойстваДляПоиска(ДанныеСтруктуры, Строка.СвойстваПоиска);
				
		// Свойства
		ЗаполнитьСвойстваДляПоиска(ДанныеСтруктуры, Строка.Свойства);
		
	КонецЦикла;
	
	УдалитьЛишниеЭлементыИзСоответствия(СтруктураДанных);	
	
КонецПроцедуры

Процедура СоздатьСтрокуСТипамиСвойств(ЗаписьXML, ТипыСвойств)
	
	Если ТипЗнч(ТипыСвойств.Значение) = ТипСоответствие Тогда
		
		Если ТипыСвойств.Значение.Количество() = 0 Тогда
			Возврат;
		КонецЕсли;
		
		ЗаписьXML.ЗаписатьНачалоЭлемента(ТипыСвойств.Ключ);
		
		Для Каждого Элемент Из ТипыСвойств.Значение Цикл
			СоздатьСтрокуСТипамиСвойств(ЗаписьXML, Элемент);
		КонецЦикла;
		
		ЗаписьXML.ЗаписатьКонецЭлемента();
		
	Иначе		
		
		одЗаписатьЭлемент(ЗаписьXML, ТипыСвойств.Ключ, ТипыСвойств.Значение);
		
	КонецЕсли;
	
КонецПроцедуры

Функция СоздатьСтрокуСТипамиДляПриемника(СтруктураДанных)
	
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	ЗаписьXML.ЗаписатьНачалоЭлемента("ИнформацияОТипахДанных");	
	
	Для Каждого Строка Из СтруктураДанных Цикл
		
		ЗаписьXML.ЗаписатьНачалоЭлемента("ТипДанных");
		УстановитьАтрибут(ЗаписьXML, "Имя", Строка.Ключ);
		
		Для Каждого СтрокаПодчинения Из Строка.Значение Цикл
			
			СоздатьСтрокуСТипамиСвойств(ЗаписьXML, СтрокаПодчинения);	
			
		КонецЦикла;
		
		ЗаписьXML.ЗаписатьКонецЭлемента();
		
	КонецЦикла;	
	
	ЗаписьXML.ЗаписатьКонецЭлемента();
	
	СтрокаРезультата = ЗаписьXML.Закрыть();
	Возврат СтрокаРезультата;
	
КонецФункции

Процедура ЗагрузитьОдинТипДанных(ПравилаОбмена, СоответствиеТипа, ИмяЛокальногоЭлемента)
	
	ИмяУзла = ИмяЛокальногоЭлемента;
	
	ПравилаОбмена.Прочитать();
	
	Если (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
		
		ПравилаОбмена.Прочитать();
		Возврат;
		
	ИначеЕсли ПравилаОбмена.ТипУзла = ТипУзлаXMLНачалоЭлемента Тогда
			
		// это новый элемент
		НовоеСоответствие = Новый Соответствие;
		СоответствиеТипа.Вставить(ИмяУзла, НовоеСоответствие);
		
		ЗагрузитьОдинТипДанных(ПравилаОбмена, НовоеСоответствие, ПравилаОбмена.ЛокальноеИмя);
		ПравилаОбмена.Прочитать();
		
	Иначе
		
		Если ПравилаОбмена.Значение = "ОпределениеТипа" Тогда
			
			СоответствиеТипа.Вставить(ИмяУзла, Тип("ОписаниеТипов")); // Необходимо привести JSON к ОписаниеТипов
			
		Иначе
			
			СоответствиеТипа.Вставить(ИмяУзла, Тип(ПравилаОбмена.Значение));
			
		КонецЕсли;
		
		ПравилаОбмена.Прочитать();
		
	КонецЕсли;
	
	ЗагрузитьСоответствиеТиповДляОдногоТипа(ПравилаОбмена, СоответствиеТипа);
	
КонецПроцедуры

Процедура ЗагрузитьСоответствиеТиповДляОдногоТипа(ПравилаОбмена, СоответствиеТипа)
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		Если (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
		    Прервать;
			
		КонецЕсли;
		
		// прочитали начало элемента
		ПравилаОбмена.Прочитать();
		
		Если ПравилаОбмена.ТипУзла = ТипУзлаXMLНачалоЭлемента Тогда
			
			// это новый элемент
			НовоеСоответствие = Новый Соответствие;
			СоответствиеТипа.Вставить(ИмяУзла, НовоеСоответствие);
			
			ЗагрузитьОдинТипДанных(ПравилаОбмена, НовоеСоответствие, ПравилаОбмена.ЛокальноеИмя);			
			
		Иначе
			
			Если ПравилаОбмена.Значение = "ОпределениеТипа" Тогда
				
				СоответствиеТипа.Вставить(ИмяУзла, Тип("ОписаниеТипов")); // Необходимо привести JSON к ОписаниеТипов
				
			Иначе
				
				СоответствиеТипа.Вставить(ИмяУзла, Тип(ПравилаОбмена.Значение));
				
			КонецЕсли;
			
			ПравилаОбмена.Прочитать();
			
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры

Процедура ЗагрузитьИнформациюОТипахДанных()
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "ТипДанных" Тогда
			
			ИмяТипа = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
			
			СоответствиеТипа = Новый Соответствие;
			СоответствиеТиповДанныхДляЗагрузки().Вставить(Тип(ИмяТипа), СоответствиеТипа);

			ЗагрузитьСоответствиеТиповДляОдногоТипа(ФайлОбмена, СоответствиеТипа);	
			
		ИначеЕсли (ИмяУзла = "ИнформацияОТипахДанных") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры

Процедура ЗагрузитьЗначенияПараметровОбменаДанными()
	
	Имя = одАтрибут(ФайлОбмена, ТипСтрока, "Имя");
	
	ТипСвойства = ТипСвойстваПоДополнительнымДанным(Неопределено, Имя);
	
	Значение = ПрочитатьСвойство(ТипСвойства);
	
	Параметры.Вставить(Имя, Значение);	
	
	АлгоритмПослеЗагрузкиПараметра = "";
	Если СобытияПослеЗагрузкиПараметров.Свойство(Имя, АлгоритмПослеЗагрузкиПараметра)
		И Не ПустаяСтрока(АлгоритмПослеЗагрузкиПараметра) Тогда
		
		Если ОтладкаОбработчиковЗагрузки Тогда
			
			ВыполнитьОбработчик_Параметры_ПослеЗагрузкиПараметра(Имя, Значение);
			
		Иначе
			
			Выполнить(АлгоритмПослеЗагрузкиПараметра);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ЗагрузитьИнформациюОПользовательскихПоляхПоиска()
	
	ИмяПравила = "";
	НастройкаПоиска = "";
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "ИмяПравила" Тогда
			
			ИмяПравила = одЗначениеЭлемента(ФайлОбмена, ТипСтрока);
			
		ИначеЕсли ИмяУзла = "НастройкаПоиска" Тогда
			
			НастройкаПоиска = одЗначениеЭлемента(ФайлОбмена, ТипСтрока);
			ИнформацияОПользовательскихПоляхПоискаПриЗагрузкеДанных.Вставить(ИмяПравила, НастройкаПоиска);	
			
		ИначеЕсли (ИмяУзла = "НастройкаПользовательскогоПоиска") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры

// Осуществляет загрузку правил обмена в соответствии с форматом.
//
// Параметры:
//   Источник     - ЧтениеXML
//                - Строка - объект, из которого осуществляется загрузка правил обмена;
//   ТипИсточника - Строка - строка, указывающая тип источника: "XMLФайл", "ЧтениеXML", "Строка".
//   СтрокаСообщенияОбОшибке - Строка - сообщение об ошибке.
//   ЗагружатьТолькоЗаголовокПравил - Булево - Истина, если требуется загрузить только заголовок правил.
// 
Процедура ЗагрузитьПравилаОбмена(Источник="",
									ТипИсточника="XMLФайл",
									СтрокаСообщенияОбОшибке = "",
									ЗагружатьТолькоЗаголовокПравил = Ложь) Экспорт
	
	ИнициализироватьМенеджерыИСообщения();
	
	ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта    = Ложь;
	ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта     = Ложь;
	
	ЕстьГлобальныйОбработчикПередКонвертациейОбъекта = Ложь;
	
	ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта    = Ложь;
	ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта     = Ложь;
	
	СоздатьСтруктуруКонвертации();
	
	ТаблицаПравилКонвертацииСвойств = Новый ТаблицаЗначений;
	ИнициализацияТаблицыПравилКонвертацииСвойств(ТаблицаПравилКонвертацииСвойств);
	
	// Возможно выбраны встроенные правила обмена (один из макетов).
	
	ИмяВременногоФайлаПравилОбмена = "";
	Если ПустаяСтрока(Источник) Тогда
		
		Источник = ИмяФайлаПравилОбмена;
		
	КонецЕсли;
	
	Если ТипИсточника="XMLФайл" Тогда
		
		Если ПустаяСтрока(Источник) Тогда
			СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(12);
			Возврат; 
		КонецЕсли;
		
		Файл = Новый Файл(Источник);
		Если Не Файл.Существует() Тогда
			СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(3);
			Возврат; 
		КонецЕсли;
		
		ПравилаОбмена = Новый ЧтениеXML();
		ПравилаОбмена.ОткрытьФайл(Источник);
		ПравилаОбмена.Прочитать();
		
	ИначеЕсли ТипИсточника="Строка" Тогда
		
		ПравилаОбмена = Новый ЧтениеXML();
		ПравилаОбмена.УстановитьСтроку(Источник);
		ПравилаОбмена.Прочитать();
		
		ЗаписатьПакетВФайлДляСборкиАрхива(Источник);
		
	ИначеЕсли ТипИсточника="ЧтениеXML" Тогда
		
		ПравилаОбмена = Источник;
		
	КонецЕсли;
		
	Если Не ((ПравилаОбмена.ЛокальноеИмя = "ПравилаОбмена") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLНачалоЭлемента)) Тогда
		СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(7);
		Возврат;
	КонецЕсли;
	
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	ЗаписьXML.ЗаписатьНачалоЭлемента("ПравилаОбмена");
	
	Пока ПравилаОбмена.Прочитать() Цикл
		
		ИмяУзла = ПравилаОбмена.ЛокальноеИмя;
		
		// Реквизиты конвертации
		Если ИмяУзла = "ВерсияФормата" Тогда
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Конвертация.Вставить("ВерсияФормата", Значение);
			
			ЗаписьXML.ЗаписатьНачалоЭлемента("ВерсияФормата");
			Стр = XMLСтрока(Значение);
			
			ЗаписьXML.ЗаписатьТекст(Стр);
			ЗаписьXML.ЗаписатьКонецЭлемента();
			
		ИначеЕсли ИмяУзла = "Ид" Тогда
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Конвертация.Вставить("Ид",                   Значение);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
		ИначеЕсли ИмяУзла = "Наименование" Тогда
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Конвертация.Вставить("Наименование",         Значение);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
		ИначеЕсли ИмяУзла = "ДатаВремяСоздания" Тогда
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипДата);
			Конвертация.Вставить("ДатаВремяСоздания",    Значение);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
		ИначеЕсли ИмяУзла = "Источник" Тогда
			
			ВерсияПлатформыИсточника = ПравилаОбмена.ПолучитьАтрибут ("ВерсияПлатформы");
			СинонимКонфигурацииИсточника = ПравилаОбмена.ПолучитьАтрибут ("СинонимКонфигурации");
			ВерсияКонфигурацииИсточника = ПравилаОбмена.ПолучитьАтрибут ("ВерсияКонфигурации");
			
			Конвертация.Вставить("ВерсияПлатформыИсточника", ВерсияПлатформыИсточника);
			Конвертация.Вставить("СинонимКонфигурацииИсточника", СинонимКонфигурацииИсточника);
			Конвертация.Вставить("ВерсияКонфигурацииИсточника", ВерсияКонфигурацииИсточника);
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Конвертация.Вставить("Источник",             Значение);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
			
		ИначеЕсли ИмяУзла = "Приемник" Тогда
			
			ВерсияПлатформыПриемника = ПравилаОбмена.ПолучитьАтрибут ("ВерсияПлатформы");
			СинонимКонфигурацииПриемника = ПравилаОбмена.ПолучитьАтрибут ("СинонимКонфигурации");
			ВерсияКонфигурацииПриемника = ПравилаОбмена.ПолучитьАтрибут ("ВерсияКонфигурации");
			
			Конвертация.Вставить("ВерсияПлатформыПриемника", ВерсияПлатформыПриемника);
			Конвертация.Вставить("СинонимКонфигурацииПриемника", СинонимКонфигурацииПриемника);
			Конвертация.Вставить("ВерсияКонфигурацииПриемника", ВерсияКонфигурацииПриемника);
			
			Значение = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Конвертация.Вставить("Приемник",             Значение);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение);
			
			Если ЗагружатьТолькоЗаголовокПравил Тогда
				Возврат;
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "РежимСовместимости" Тогда
			// Поддержка обратной совместимости.
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "Комментарий" Тогда
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "ОсновнойПланОбмена" Тогда
			одПропустить(ПравилаОбмена);
			
		ИначеЕсли ИмяУзла = "Параметры" Тогда
			ЗагрузитьПараметры(ПравилаОбмена, ЗаписьXML)

		// События конвертации
		
		ИначеЕсли ИмяУзла = "" Тогда
		
		ИначеЕсли ИмяУзла = "ПослеЗагрузкиПравилОбмена" Тогда
			Конвертация.Вставить("ПослеЗагрузкиПравилОбмена", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПослеЗагрузкиПравилОбмена","Конвертация_ПослеЗагрузкиПравилОбмена");
				
		ИначеЕсли ИмяУзла = "ПередВыгрузкойДанных" Тогда
			Конвертация.Вставить("ПередВыгрузкойДанных", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПередВыгрузкойДанных","Конвертация_ПередВыгрузкойДанных");
			
		ИначеЕсли ИмяУзла = "ПередПолучениемИзмененныхОбъектов" Тогда
			Конвертация.Вставить("ПередПолучениемИзмененныхОбъектов", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПередПолучениемИзмененныхОбъектов","Конвертация_ПередПолучениемИзмененныхОбъектов");
			
		ИначеЕсли ИмяУзла = "ПослеПолученияИнформацииОбУзлахОбмена" Тогда
			
			Конвертация.Вставить("ПослеПолученияИнформацииОбУзлахОбмена", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПослеПолученияИнформацииОбУзлахОбмена","Конвертация_ПослеПолученияИнформацииОбУзлахОбмена");
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Конвертация.ПослеПолученияИнформацииОбУзлахОбмена);
						
		ИначеЕсли ИмяУзла = "ПослеВыгрузкиДанных" Тогда
			Конвертация.Вставить("ПослеВыгрузкиДанных",  одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПослеВыгрузкиДанных","Конвертация_ПослеВыгрузкиДанных");
			
		ИначеЕсли ИмяУзла = "ПередОтправкойИнформацииОбУдалении" Тогда
			Конвертация.Вставить("ПередОтправкойИнформацииОбУдалении",  одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПередОтправкойИнформацииОбУдалении","Конвертация_ПередОтправкойИнформацииОбУдалении");

		ИначеЕсли ИмяУзла = "ПередВыгрузкойОбъекта" Тогда
			Конвертация.Вставить("ПередВыгрузкойОбъекта", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПередВыгрузкойОбъекта","Конвертация_ПередВыгрузкойОбъекта");
			ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта = Не ПустаяСтрока(Конвертация.ПередВыгрузкойОбъекта);

		ИначеЕсли ИмяУзла = "ПослеВыгрузкиОбъекта" Тогда
			Конвертация.Вставить("ПослеВыгрузкиОбъекта", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПослеВыгрузкиОбъекта","Конвертация_ПослеВыгрузкиОбъекта");
			ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта = Не ПустаяСтрока(Конвертация.ПослеВыгрузкиОбъекта);

		ИначеЕсли ИмяУзла = "ПередЗагрузкойОбъекта" Тогда
			Конвертация.Вставить("ПередЗагрузкойОбъекта", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПередЗагрузкойОбъекта","Конвертация_ПередЗагрузкойОбъекта");
			ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта = Не ПустаяСтрока(Конвертация.ПередЗагрузкойОбъекта);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Конвертация.ПередЗагрузкойОбъекта);

		ИначеЕсли ИмяУзла = "ПослеЗагрузкиОбъекта" Тогда
			Конвертация.Вставить("ПослеЗагрузкиОбъекта", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПослеЗагрузкиОбъекта","Конвертация_ПослеЗагрузкиОбъекта");
			ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта = Не ПустаяСтрока(Конвертация.ПослеЗагрузкиОбъекта);
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Конвертация.ПослеЗагрузкиОбъекта);

		ИначеЕсли ИмяУзла = "ПередКонвертациейОбъекта" Тогда
			Конвертация.Вставить("ПередКонвертациейОбъекта", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПередКонвертациейОбъекта","Конвертация_ПередКонвертациейОбъекта");
			ЕстьГлобальныйОбработчикПередКонвертациейОбъекта = Не ПустаяСтрока(Конвертация.ПередКонвертациейОбъекта);
			
		ИначеЕсли ИмяУзла = "ПередЗагрузкойДанных" Тогда
			Конвертация.ПередЗагрузкойДанных = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Конвертация.Вставить("ИмяОбработчикаПередЗагрузкойДанных","Конвертация_ПередЗагрузкойДанных");
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Конвертация.ПередЗагрузкойДанных);
			
		ИначеЕсли ИмяУзла = "ПослеЗагрузкиДанных" Тогда
            Конвертация.ПослеЗагрузкиДанных = одЗначениеЭлемента(ПравилаОбмена, ТипСтрока);
			Конвертация.Вставить("ИмяОбработчикаПослеЗагрузкиДанных","Конвертация_ПослеЗагрузкиДанных");
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Конвертация.ПослеЗагрузкиДанных);
			
		ИначеЕсли ИмяУзла = "ПослеЗагрузкиПараметров" Тогда
            Конвертация.Вставить("ПослеЗагрузкиПараметров", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПослеЗагрузкиПараметров","Конвертация_ПослеЗагрузкиПараметров");
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Конвертация.ПослеЗагрузкиПараметров);
			
		ИначеЕсли ИмяУзла = "ПриПолученииИнформацииОбУдалении" Тогда
            Конвертация.Вставить("ПриПолученииИнформацииОбУдалении", одЗначениеЭлемента(ПравилаОбмена, ТипСтрока));
			Конвертация.Вставить("ИмяОбработчикаПриПолученииИнформацииОбУдалении","Конвертация_ПриПолученииИнформацииОбУдалении");
			одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Конвертация.ПриПолученииИнформацииОбУдалении);
			
		ИначеЕсли ИмяУзла = "УдалятьСопоставленныеОбъектыВПриемникеПриИхУдаленииВИсточнике" Тогда
            Конвертация.УдалятьСопоставленныеОбъектыВПриемникеПриИхУдаленииВИсточнике = одЗначениеЭлемента(ПравилаОбмена, ТипБулево);
						
		// Правила
		
		ИначеЕсли ИмяУзла = "ПравилаВыгрузкиДанных" Тогда
			Если РежимОбмена = "Загрузка" Тогда
				одПропустить(ПравилаОбмена);
			Иначе
				ЗагрузитьПравилаВыгрузки(ПравилаОбмена);
			КонецЕсли; 
			
		ИначеЕсли ИмяУзла = "ПравилаКонвертацииОбъектов" Тогда
			ЗагрузитьПравилаКонвертации(ПравилаОбмена, ЗаписьXML);
			
		ИначеЕсли ИмяУзла = "ПравилаОчисткиДанных" Тогда
			ЗагрузитьПравилаОчистки(ПравилаОбмена, ЗаписьXML)
		
		ИначеЕсли ИмяУзла = "ПравилаРегистрацииОбъектов" Тогда
			одПропустить(ПравилаОбмена);
			
		// Алгоритмы, Запросы, Обработки.
		
		ИначеЕсли ИмяУзла = "Алгоритмы" Тогда
			ЗагрузитьАлгоритмы(ПравилаОбмена, ЗаписьXML);
			
		ИначеЕсли ИмяУзла = "Запросы" Тогда
			ЗагрузитьЗапросы(ПравилаОбмена, ЗаписьXML);

		ИначеЕсли ИмяУзла = "Обработки" Тогда
			ЗагрузитьОбработки(ПравилаОбмена, ЗаписьXML);
			
		// Выход
		ИначеЕсли (ИмяУзла = "ПравилаОбмена") И (ПравилаОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			Если РежимОбмена <> "Загрузка" Тогда
				ПравилаОбмена.Закрыть();
			КонецЕсли;
			Прервать;

			
		// Ошибка формата
		Иначе
			СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(7);
			Возврат;
		КонецЕсли;
	КонецЦикла;
	
	ЗаписьXML.ЗаписатьКонецЭлемента();
	XMLПравила = ЗаписьXML.Закрыть();
	
	// Удаляем временный файл правил.
	Если Не ПустаяСтрока(ИмяВременногоФайлаПравилОбмена) Тогда
		Попытка
			УдалитьФайлы(ИмяВременногоФайлаПравилОбмена);
		Исключение
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Обмен данными'", ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецПопытки;
	КонецЕсли;
	
	Если ЗагружатьТолькоЗаголовокПравил Тогда
		Возврат;
	КонецЕсли;
	
	// Дополнительно нужна информация по типам данных приемника для быстрой загрузки данных.
	СтруктураДанных = Новый Соответствие();
	ЗаполнитьИнформациюПоТипамДанныхПриемника(СтруктураДанных, ТаблицаПравилКонвертации);
	
	СтрокаТиповДляПриемника = СоздатьСтрокуСТипамиДляПриемника(СтруктураДанных);
	
	ИмяПрофиляБезопасности = ИнициализироватьОбработки();
	
	Если ИмяПрофиляБезопасности <> Неопределено Тогда
		УстановитьБезопасныйРежим(ИмяПрофиляБезопасности);
	КонецЕсли;
	
	// Нужно вызвать событие после загрузки правил обмена.
	ТекстСобытияПослеЗагрузкиПравилОбмена = "";
	Если РежимОбмена <> "Загрузка" И Конвертация.Свойство("ПослеЗагрузкиПравилОбмена", ТекстСобытияПослеЗагрузкиПравилОбмена)
		И Не ПустаяСтрока(ТекстСобытияПослеЗагрузкиПравилОбмена) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиПравилОбмена();
				
			Иначе
				
				Выполнить(ТекстСобытияПослеЗагрузкиПравилОбмена);
				
			КонецЕсли;
			
		Исключение
			СтрокаСообщенияОбОшибке = ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(75, 
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), 
				НСтр("ru = 'ПослеЗагрузкиПравилОбмена (конвертация)'"));
			
			Если Не ПродолжитьПриОшибке Тогда
				ВызватьИсключение СтрокаСообщенияОбОшибке;
			КонецЕсли;
			
		КонецПопытки;
		
	КонецЕсли;
	
	ИнициализироватьПервоначальныеЗначенияПараметров();
	
КонецПроцедуры

Процедура ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки = Неопределено)
	
	УвеличитьСчетчикЗагруженныхОбъектов();
	
	Если СчетчикЗагруженныхОбъектов() % 100 = 0
		И ГлобальныйСтекНеЗаписанныхОбъектов.Количество() > 100 Тогда
		
		ПровестиЗаписьНеЗаписанныхОбъектов();
		
	КонецЕсли;
	
	// При загрузке в режиме внешнего соединения управление транзакциями выполняется из управляющего приложения.
	Если Не ЗагрузкаДанныхВыполняетсяЧерезВнешнееСоединение Тогда
		
		Если ИспользоватьТранзакции
			И КоличествоОбъектовНаТранзакцию > 0 
			И СчетчикЗагруженныхОбъектов() % КоличествоОбъектовНаТранзакцию = 0 Тогда
			
			ЗафиксироватьТранзакцию();
			НачатьТранзакцию();
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

Процедура УдалитьОбъектПоСсылке(Ссылка, СтрокаСообщенияОбОшибке)
	
	Объект = Ссылка.ПолучитьОбъект();
	
	Если Объект = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ОбменДаннымиСобытия.ЗагрузкаЗапрещена(Объект, УзелОбменаЗагрузкаДанныхОбъект) Тогда
		Возврат;
	КонецЕсли;
	
	УстановитьОбменДаннымиЗагрузка(Объект);
	
	Если Не ПустаяСтрока(Конвертация.ПриПолученииИнформацииОбУдалении) Тогда
		
		Отказ = Ложь;
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПриПолученииИнформацииОбУдалении(Объект, Отказ);
				
			Иначе
				
				Выполнить(Конвертация.ПриПолученииИнформацииОбУдалении);
				
			КонецЕсли;
			
		Исключение
			СтрокаСообщенияОбОшибке = ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(77,
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				НСтр("ru = 'ПриПолученииИнформацииОбУдалении (конвертация)'"));
				
			Отказ = Истина;
			
			Если Не ПродолжитьПриОшибке Тогда
				ВызватьИсключение СтрокаСообщенияОбОшибке;
			КонецЕсли;
			
		КонецПопытки;
		
		Если Отказ Тогда
			Возврат;
		КонецЕсли;
		
	КонецЕсли;
	
	УдалитьОбъект(Объект, Истина);
	
КонецПроцедуры

Процедура ПрочитатьУдалениеОбъекта(СтрокаСообщенияОбОшибке)
	
	ТипИсточникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипПриемника");
	ТипПриемникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипИсточника");
	
	УникальныйИдентификаторСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "УникальныйИдентификатор");
	
	ВыполнитьЗаменуУникальногоИдентификатораПриНеобходимости(УникальныйИдентификаторСтрокой, ТипИсточникаСтрокой, ТипПриемникаСтрокой, Истина);
	
	СтруктураСвойств = Менеджеры[Тип(ТипИсточникаСтрокой)];
	
	Ссылка = СтруктураСвойств.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(УникальныйИдентификаторСтрокой));
	
	УдалитьОбъектПоСсылке(Ссылка, СтрокаСообщенияОбОшибке);
	
КонецПроцедуры

Процедура ВыполнитьВыборочноеЧтениеСообщения(ТаблицыДляЗагрузки)
	
	Если ТаблицыДляЗагрузки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ЧтениеСообщения = Неопределено; // см. ОписаниеЧтенияСообщения
	Попытка
		
		УстановитьФлагОшибки(Ложь);
		
		ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных();
		
		ИнформацияОПользовательскихПоляхПоискаПриЗагрузкеДанных = Новый Соответствие;
		СоответствиеДопПараметровПоиска = Новый Соответствие;
		СоответствиеПравилКонвертации = Новый Соответствие;
		
		// Инициализируем ведение протокола обмена.
		ИнициализироватьВедениеПротоколаОбмена();
		
		Если КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 0 Тогда
			КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 100;
		КонецЕсли;
		
		ГлобальныйСтекНеЗаписанныхОбъектов = Новый Соответствие;
		
		ПолеСчетчикЗагруженныхОбъектов = Неопределено;
		НомерПоследнегоПоискаПоСсылке  = 0;
		
		ИнициализироватьМенеджерыИСообщения();
		
		НачатьЧтениеСообщения(ЧтениеСообщения, Истина);
		
		Если ИспользоватьТранзакции Тогда
			НачатьТранзакцию();
		КонецЕсли;
		Попытка
			
			ПроизвестиЧтениеДанныхДляТаблиц(ТаблицыДляЗагрузки);
			
			Если ФлагОшибки() Тогда
				ВызватьИсключение НСтр("ru = 'Возникли ошибки при загрузке данных.'");
			КонецЕсли;
			
			// Отложенная запись того, что не записали.
			ПровестиЗаписьНеЗаписанныхОбъектов();
			
			ВыполнитьОбработчикПослеЗагрузкиДанных();
			
			Если ФлагОшибки() Тогда
				ВызватьИсключение НСтр("ru = 'Возникли ошибки при загрузке данных.'");
			КонецЕсли;
			
			Если ИспользоватьТранзакции Тогда
				ЗафиксироватьТранзакцию();
			КонецЕсли;
		Исключение
			Если ИспользоватьТранзакции Тогда
				ОтменитьТранзакцию();
			КонецЕсли;
			ПрерватьЧтениеСообщения(ЧтениеСообщения);
			ВызватьИсключение;
		КонецПопытки;
		
		// Выполняем проведение документов в очереди.
		ВыполнитьОтложенноеПроведениеДокументов();
		ВыполнитьОтложеннуюЗаписьОбъектов();
		
		ЗакончитьЧтениеСообщения(ЧтениеСообщения);
		
	Исключение
		Если ЧтениеСообщения <> Неопределено
			И ЧтениеСообщения.СообщениеБылоПринятоРанее Тогда
			ЗаписатьВПротоколВыполнения(174,,,,,,
				Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято);
		Иначе
			ЗаписатьВПротоколВыполнения(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецЕсли;
	КонецПопытки;
	
	ЗавершитьВедениеПротоколаОбмена();
	
КонецПроцедуры

Процедура ПроизвестиЧтениеДанных(ЧтениеСообщения)
	
	СтрокаСообщенияОбОшибке = "";
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Объект" Тогда
			
			ОбменДаннымиСервер.РассчитатьПроцентЗагрузки(СчетчикЗагруженныхОбъектов(), КоличествоОбъектовКЗагрузке, РазмерФайлаСообщенияОбмена);
			ПоследнийОбъектЗагрузки = ПрочитатьОбъект();
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки);
			
		ИначеЕсли ИмяУзла = "НаборЗаписейРегистра" Тогда
			
			// набор записей регистра
			ПоследнийОбъектЗагрузки = ПрочитатьНаборЗаписейРегистра();
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки);
			
		ИначеЕсли ИмяУзла = "УдалениеОбъекта" Тогда
			
			// Обработка удаления объекта из информационной базы.
			ПрочитатьУдалениеОбъекта(СтрокаСообщенияОбОшибке);
			
			одПропустить(ФайлОбмена, "УдалениеОбъекта");
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента();
			
		ИначеЕсли ИмяУзла = "ИнформацияОРегистрацииОбъекта" Тогда
			
			ЕстьИнформацияОРегистрацииОбъекта = Истина;
			
			ПоследнийОбъектЗагрузки = ПрочитатьИнформациюОРегистрацииОбъекта();
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки);
			
		ИначеЕсли ИмяУзла = "КорректировкаИнформацииОРегистрацииОбъекта" Тогда
			
			ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Истина;
			
			ПрочитатьКорректировкуИнформацииСопоставления();
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли ИмяУзла = "ОбщиеДанныеУзлов" Тогда
			
			ПрочитатьОбщиеДанныеУзлов(ЧтениеСообщения);
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли (ИмяУзла = "ФайлОбмена") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать; // выходим
			
		Иначе
			
			ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
			
		КонецЕсли;
		
		// Прерываем цикл чтения файла в случае возникновения ошибки загрузки.
		Если ФлагОшибки() Тогда
			ВызватьИсключение НСтр("ru = 'Возникли ошибки при загрузке данных.'");
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПроизвестиЧтениеДанныхДляТаблиц(ТаблицыДляЗагрузки)
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Объект" Тогда
			
			ТипОбъектаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "Тип");
			
			Если ТипОбъектаСтрокой = "КонстантыНабор" Тогда
				
				ИмяКонстанты = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяКонстанты");
				
				ТипИсточникаСтрокой = ИмяКонстанты;
				ТипПриемникаСтрокой = ИмяКонстанты;
				
			Иначе
				
				ИмяПравила = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПравила");
				
				ПКО = Правила[ИмяПравила];
				
				ТипИсточникаСтрокой = ПКО.ТипИсточника;
				ТипПриемникаСтрокой = ПКО.ТипПриемника;
				
			КонецЕсли;
			
			КлючТаблицыДанных = ОбменДаннымиСервер.КлючТаблицыДанных(ТипИсточникаСтрокой, ТипПриемникаСтрокой, Ложь);
			
			Если ТаблицыДляЗагрузки.Найти(КлючТаблицыДанных) <> Неопределено Тогда
				
				Если РежимЗагрузкиДанныхВИнформационнуюБазу() Тогда // Загрузка в информационную базу.
					
					ОбработатьОкончаниеЧтенияНовогоЭлемента(ПрочитатьОбъект());
					
				Иначе // Загрузка в таблицу значений.
					
					УникальныйИдентификаторСтрокой = "";
					
					ПоследнийОбъектЗагрузки = ПрочитатьОбъект(УникальныйИдентификаторСтрокой);
					
					Если ПоследнийОбъектЗагрузки <> Неопределено Тогда
						
						ТаблицаДанныхСообщенияОбмена = ТаблицыДанныхСообщенияОбмена().Получить(КлючТаблицыДанных);
						
						СтрокаТаблицы = ТаблицаДанныхСообщенияОбмена.Найти(УникальныйИдентификаторСтрокой, ИмяКолонкиУникальныйИдентификатор());
						
						Если СтрокаТаблицы = Неопределено Тогда
							
							УвеличитьСчетчикЗагруженныхОбъектов();
							
							СтрокаТаблицы = ТаблицаДанныхСообщенияОбмена.Добавить();
							
							СтрокаТаблицы[ИмяКолонкиТипСтрокой()]              = ТипПриемникаСтрокой;
							СтрокаТаблицы["Ссылка"]                            = ПоследнийОбъектЗагрузки.Ссылка;
							СтрокаТаблицы[ИмяКолонкиУникальныйИдентификатор()] = УникальныйИдентификаторСтрокой;
							
						КонецЕсли;
						
						// Заполняем значения свойств объекта.
						ЗаполнитьЗначенияСвойств(СтрокаТаблицы, ПоследнийОбъектЗагрузки);
						
					КонецЕсли;
					
				КонецЕсли;
				
			Иначе
				
				одПропустить(ФайлОбмена, ИмяУзла);
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "НаборЗаписейРегистра" Тогда
			
			Если РежимЗагрузкиДанныхВИнформационнуюБазу() Тогда
				
				ИмяПравила = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПравила");
				
				ПКО = Правила[ИмяПравила];
				
				ТипИсточникаСтрокой = ПКО.ТипИсточника;
				ТипПриемникаСтрокой = ПКО.ТипПриемника;
				
				КлючТаблицыДанных = ОбменДаннымиСервер.КлючТаблицыДанных(ТипИсточникаСтрокой, ТипПриемникаСтрокой, Ложь);
				
				Если ТаблицыДляЗагрузки.Найти(КлючТаблицыДанных) <> Неопределено Тогда
					
					ОбработатьОкончаниеЧтенияНовогоЭлемента(ПрочитатьНаборЗаписейРегистра());
					
				Иначе
					
					одПропустить(ФайлОбмена, ИмяУзла);
					
				КонецЕсли;
				
			Иначе
				
				одПропустить(ФайлОбмена, ИмяУзла);
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "УдалениеОбъекта" Тогда
			
			ТипПриемникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипПриемника");
			ТипИсточникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипИсточника");
			
			КлючТаблицыДанных = ОбменДаннымиСервер.КлючТаблицыДанных(ТипИсточникаСтрокой, ТипПриемникаСтрокой, Истина);
			
			Если ТаблицыДляЗагрузки.Найти(КлючТаблицыДанных) <> Неопределено Тогда
				
				Если РежимЗагрузкиДанныхВИнформационнуюБазу() Тогда // Загрузка в информационную базу.
					
					// Обработка удаления объекта из информационной базы.
					ПрочитатьУдалениеОбъекта("");
					
					ОбработатьОкончаниеЧтенияНовогоЭлемента();
					
				Иначе // Загрузка в таблицу значений.
					
					УникальныйИдентификаторСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "УникальныйИдентификатор");
					
					// Добавляем удаление объекта в таблицу данных сообщения.
					ТаблицаДанныхСообщенияОбмена = ТаблицыДанныхСообщенияОбмена().Получить(КлючТаблицыДанных);
					
					СтрокаТаблицы = ТаблицаДанныхСообщенияОбмена.Найти(УникальныйИдентификаторСтрокой, ИмяКолонкиУникальныйИдентификатор());
					
					Если СтрокаТаблицы = Неопределено Тогда
						
						УвеличитьСчетчикЗагруженныхОбъектов();
						
						СтрокаТаблицы = ТаблицаДанныхСообщенияОбмена.Добавить();
						
						// Заполняем значения всех полей таблицы значением по умолчанию.
						Для Каждого Колонка Из ТаблицаДанныхСообщенияОбмена.Колонки Цикл
							
							// фильтр
							Если    Колонка.Имя = ИмяКолонкиТипСтрокой()
								ИЛИ Колонка.Имя = ИмяКолонкиУникальныйИдентификатор()
								ИЛИ Колонка.Имя = "Ссылка" Тогда
								Продолжить;
							КонецЕсли;
							
							Если Колонка.ТипЗначения.СодержитТип(ТипСтрока) Тогда
								
								СтрокаТаблицы[Колонка.Имя] = НСтр("ru = 'Удаление объекта'");
								
							КонецЕсли;
							
						КонецЦикла;
						
						СтруктураСвойств = Менеджеры[Тип(ТипПриемникаСтрокой)];
						
						СсылкаНаУдаляемыйОбъект = СтруктураСвойств.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(УникальныйИдентификаторСтрокой));
						
						СтрокаТаблицы[ИмяКолонкиТипСтрокой()]              = ТипПриемникаСтрокой;
						СтрокаТаблицы["Ссылка"]                            = СсылкаНаУдаляемыйОбъект;
						СтрокаТаблицы[ИмяКолонкиУникальныйИдентификатор()] = УникальныйИдентификаторСтрокой;
						
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЕсли;
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли ИмяУзла = "ИнформацияОРегистрацииОбъекта" Тогда
			
			одПропустить(ФайлОбмена, ИмяУзла); // В режиме выборочного чтения сообщения пропускаем элемент.
			
		ИначеЕсли ИмяУзла = "КорректировкаИнформацииОРегистрацииОбъекта" Тогда
			
			одПропустить(ФайлОбмена, ИмяУзла); // В режиме выборочного чтения сообщения пропускаем элемент.
			
		ИначеЕсли ИмяУзла = "ОбщиеДанныеУзлов" Тогда
			
			одПропустить(ФайлОбмена, ИмяУзла); // В режиме выборочного чтения сообщения пропускаем элемент.
			
		ИначеЕсли (ИмяУзла = "ФайлОбмена") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать; // выходим
			
		Иначе
			
			ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
			
		КонецЕсли;
		
		// Прерываем цикл чтения файла в случае возникновения ошибки.
		Если ФлагОшибки() Тогда
			ВызватьИсключение НСтр("ru = 'Возникли ошибки при загрузке данных.'");
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Под классификатором понимаем справочник, ПВХ, план счетов, ПВР, у которых
// в ПКО выставлены флаги СинхронизироватьПоИдентификатору И ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли.
//
Функция ЭтоОбъектКлассификатор(ТипОбъектаСтрокой, ПКО)
	
	ВидОбъекта = ТипОбъектаСтрокой;
	Позиция = СтрНайти(ВидОбъекта, ".");
	Если Позиция > 0 Тогда
		ВидОбъекта = Лев(ВидОбъекта, Позиция - 1);
	КонецЕсли;
	
	Если    ВидОбъекта = "СправочникСсылка"
		Или ВидОбъекта = "ПланВидовХарактеристикСсылка"
		Или ВидОбъекта = "ПланСчетовСсылка"
		Или ВидОбъекта = "ПланВидовРасчетаСсылка" Тогда
		Возврат ПКО.СинхронизироватьПоИдентификатору И ПКО.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли
	КонецЕсли; 
	
	Возврат Ложь;
КонецФункции

Процедура ПроизвестиЧтениеДанныхВРежимеАнализа(ЧтениеСообщения, ПараметрыАнализа = Неопределено)
	
	// Параметры по умолчанию
	ПараметрыСбораСтатистики = Новый Структура("СобиратьСтатистикуКлассификаторов", Ложь);
	Если ПараметрыАнализа <> Неопределено Тогда
		ЗаполнитьЗначенияСвойств(ПараметрыСбораСтатистики, ПараметрыАнализа);
	КонецЕсли;
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Объект" Тогда
			
			ТипОбъектаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "Тип");
			
			Если ТипОбъектаСтрокой <> "КонстантыНабор" Тогда
				
				ИмяПравила = одАтрибут(ФайлОбмена, ТипСтрока, "ИмяПравила");
				ПКО        = Правила[ИмяПравила];
				
				Если ПараметрыСбораСтатистики.СобиратьСтатистикуКлассификаторов И ЭтоОбъектКлассификатор(ТипОбъектаСтрокой, ПКО) Тогда
					// Новое поведение
					СобиратьСтатистику = Истина;
					ЭтоКлассификатор   = Истина;
					
				ИначеЕсли Не (ПКО.СинхронизироватьПоИдентификатору И ПКО.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли) И ПКО.СинхронизироватьПоИдентификатору Тогда
					// Ветка совместимости.
					// Объекты, для которых выполняется автоматическое сопоставление в процессе обмена (классификаторы), 
					// не отображаются пользователю в таблице информации статистики. Поэтому сбор информации статистики для них не
					// нужен.

					// Также не отображаются объекты, которые идентифицируются по полям поиска, а не по уникальному идентификатору
					// ссылки.
					СобиратьСтатистику = Истина;
					ЭтоКлассификатор   = Ложь;
					
				Иначе 
					СобиратьСтатистику = Ложь;
					
				КонецЕсли;
				
				Если СобиратьСтатистику Тогда
					СтрокаТаблицы = ТаблицаДанныхЗаголовкаПакета().Добавить();
					
					СтрокаТаблицы.ТипОбъектаСтрокой = ТипОбъектаСтрокой;
					СтрокаТаблицы.КоличествоОбъектовВИсточнике = 1;
					
					СтрокаТаблицы.ТипПриемникаСтрокой = ПКО.ТипПриемника;
					СтрокаТаблицы.ТипИсточникаСтрокой = ПКО.ТипИсточника;
					
					СтрокаТаблицы.ПоляПоиска  = ПоляПоискаМеханизмаСопоставленияОбъектов(ПКО.ПоляПоиска);
					СтрокаТаблицы.ПоляТаблицы = ПКО.ПоляТаблицы;
					
					СтрокаТаблицы.СинхронизироватьПоИдентификатору    = ПКО.СинхронизироватьПоИдентификатору;
					СтрокаТаблицы.ИспользоватьПредварительныйПросмотр = ПКО.СинхронизироватьПоИдентификатору;
					СтрокаТаблицы.ЭтоКлассификатор   = ЭтоКлассификатор;
					СтрокаТаблицы.ЭтоУдалениеОбъекта = Ложь;

				КонецЕсли;
				
			КонецЕсли;
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли ИмяУзла = "НаборЗаписейРегистра" Тогда
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли ИмяУзла = "УдалениеОбъекта" Тогда
			
			СтрокаТаблицы = ТаблицаДанныхЗаголовкаПакета().Добавить();
			
			СтрокаТаблицы.ТипПриемникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипПриемника");
			СтрокаТаблицы.ТипИсточникаСтрокой = одАтрибут(ФайлОбмена, ТипСтрока, "ТипИсточника");
			
			СтрокаТаблицы.ТипОбъектаСтрокой = СтрокаТаблицы.ТипПриемникаСтрокой;
			
			СтрокаТаблицы.КоличествоОбъектовВИсточнике = 1;
			
			СтрокаТаблицы.СинхронизироватьПоИдентификатору = Ложь;
			СтрокаТаблицы.ИспользоватьПредварительныйПросмотр = Истина;
			СтрокаТаблицы.ЭтоКлассификатор = Ложь;
			СтрокаТаблицы.ЭтоУдалениеОбъекта = Истина;
			
			СтрокаТаблицы.ПоляПоиска = ""; // Поля поиска будут назначены в конструкторе обработки сопоставления объектов.
			
			// Определяем значения для колонки ПоляТаблицы
			// получаем описание всех полей объекта метаданного из конфигурации.
			ТипОбъекта = Тип(СтрокаТаблицы.ТипОбъектаСтрокой);
			ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипОбъекта);
			
			МассивПодстрок = ТаблицаОписанияСвойствОбъекта(ОбъектМетаданных).ВыгрузитьКолонку("Имя");
			
			// Удаляем поле "Ссылка" из визуальных полей таблицы.
			ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(МассивПодстрок, "Ссылка");
			
			СтрокаТаблицы.ПоляТаблицы = СтрСоединить(МассивПодстрок, ",");
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли ИмяУзла = "ИнформацияОРегистрацииОбъекта" Тогда
			
			ЕстьИнформацияОРегистрацииОбъекта = Истина;
			
			ПоследнийОбъектЗагрузки = ПрочитатьИнформациюОРегистрацииОбъекта();
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки);
			
		ИначеЕсли ИмяУзла = "КорректировкаИнформацииОРегистрацииОбъекта" Тогда
			
			ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Истина;
			
			ПрочитатьКорректировкуИнформацииСопоставления();
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли ИмяУзла = "ОбщиеДанныеУзлов" Тогда
			
			ПрочитатьОбщиеДанныеУзлов(ЧтениеСообщения);
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли (ИмяУзла = "ФайлОбмена") И (ФайлОбмена.ТипУзла = ТипУзлаXML.КонецЭлемента) Тогда
			
			Прервать; // выход
			
		Иначе
			
			ВызватьИсключение НСтр("ru = 'Ошибка формата сообщения обмена.'");
			
		КонецЕсли;
		
		// Прерываем цикл чтения файла в случае возникновения ошибки.
		Если ФлагОшибки() Тогда
			ВызватьИсключение НСтр("ru = 'Возникли ошибки при анализе данных.'");
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПроизвестиЧтениеДанныхВРежимеВнешнегоСоединения(ЧтениеСообщения)
	
	СтрокаСообщенияОбОшибке = "";
	КоличествоОбъектовКЗагрузке = КоличествоОбъектовКЗагрузкеВнешнееСоединение;
	
	Пока ФайлОбмена.Прочитать() Цикл
		
		ИмяУзла = ФайлОбмена.ЛокальноеИмя;
		
		Если ИмяУзла = "Объект" Тогда
			
			ПоследнийОбъектЗагрузки = ПрочитатьОбъект();
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки);
			
			ОбменДаннымиСервер.РассчитатьПроцентЗагрузки(СчетчикЗагруженныхОбъектов(), КоличествоОбъектовКЗагрузке, РазмерФайлаСообщенияОбмена);
			
		ИначеЕсли ИмяУзла = "НаборЗаписейРегистра" Тогда
			
			// набор записей регистра
			ПоследнийОбъектЗагрузки = ПрочитатьНаборЗаписейРегистра();
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки);
			ОбменДаннымиСервер.РассчитатьПроцентЗагрузки(СчетчикЗагруженныхОбъектов(), КоличествоОбъектовКЗагрузке, РазмерФайлаСообщенияОбмена);
		ИначеЕсли ИмяУзла = "УдалениеОбъекта" Тогда
			
			// Обработка удаления объекта из информационной базы.
			ПрочитатьУдалениеОбъекта(СтрокаСообщенияОбОшибке);
			
			одПропустить(ФайлОбмена, "УдалениеОбъекта");
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента();
			ОбменДаннымиСервер.РассчитатьПроцентЗагрузки(СчетчикЗагруженныхОбъектов(), КоличествоОбъектовКЗагрузке, РазмерФайлаСообщенияОбмена);
		ИначеЕсли ИмяУзла = "ИнформацияОРегистрацииОбъекта" Тогда
			
			ЕстьИнформацияОРегистрацииОбъекта = Истина;
			
			ПоследнийОбъектЗагрузки = ПрочитатьИнформациюОРегистрацииОбъекта();
			
			ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки);
			
		ИначеЕсли ИмяУзла = "НастройкаПользовательскогоПоиска" Тогда
			
			ЗагрузитьИнформациюОПользовательскихПоляхПоиска();
			
		ИначеЕсли ИмяУзла = "ИнформацияОТипахДанных" Тогда
			
			Если СоответствиеТиповДанныхДляЗагрузки().Количество() > 0 Тогда
				
				одПропустить(ФайлОбмена, ИмяУзла);
				
			Иначе
				ЗагрузитьИнформациюОТипахДанных();
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ЗначениеПараметра" Тогда	
			
			ЗагрузитьЗначенияПараметровОбменаДанными();
			
		ИначеЕсли ИмяУзла = "АлгоритмПослеЗагрузкиПараметров" Тогда
			
			Отказ = Ложь;
			ПричинаОтказа = "";
			
			ТекстАлгоритма = одЗначениеЭлемента(ФайлОбмена, ТипСтрока);
			
			Если Не ПустаяСтрока(ТекстАлгоритма) Тогда
				
				Попытка
					
					Если ОтладкаОбработчиковЗагрузки Тогда
						
						ВыполнитьОбработчик_Конвертация_ПослеЗагрузкиПараметров(ФайлОбмена, Отказ, ПричинаОтказа);
						
					Иначе
						
						Выполнить(ТекстАлгоритма);
						
					КонецЕсли;
					
					Если Отказ = Истина Тогда
						
						Если Не ПустаяСтрока(ПричинаОтказа) Тогда
							
							СтрокаСообщения = НСтр("ru = 'Загрузка данных отменена по причине: %1'");
							СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ПричинаОтказа);
							ВызватьИсключение СтрокаСообщения;
						Иначе
							ВызватьИсключение НСтр("ru = 'Загрузка данных отменена'");
						КонецЕсли;
						
					КонецЕсли;
					
				Исключение
					
					ЗП = ЗаписьПротоколаОбмена(78, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
					ЗП.Обработчик     = "ПослеЗагрузкиПараметров";
					СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(78, ЗП, Истина);
					
					Если Не ПродолжитьПриОшибке Тогда
						ВызватьИсключение СтрокаСообщенияОбОшибке;
					КонецЕсли;
					
				КонецПопытки;
				
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ДанныеПоОбмену" Тогда
			
			ПрочитатьДанныеПоОбмену(ЧтениеСообщения, Ложь);
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
			Если ФлагОшибки() Тогда
				Прервать;
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "ОбщиеДанныеУзлов" Тогда
			
			ПрочитатьОбщиеДанныеУзлов(Неопределено);
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
			Если ФлагОшибки() Тогда
				Прервать;
			КонецЕсли;
			
		ИначеЕсли ИмяУзла = "КорректировкаИнформацииОРегистрацииОбъекта" Тогда
			
			ПрочитатьКорректировкуИнформацииСопоставления();
			
			ЕстьКорректировкаИнформацииОРегистрацииОбъекта = Истина;
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		ИначеЕсли (ИмяУзла = "ФайлОбмена") И (ФайлОбмена.ТипУзла = ТипУзлаXMLКонецЭлемента) Тогда
			
			Прервать; // выходим
			
		Иначе
			
			одПропустить(ФайлОбмена, ИмяУзла);
			
		КонецЕсли;
		
		// Прерываем цикл чтения файла в случае возникновения ошибки загрузки.
		Если ФлагОшибки() Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
		
КонецПроцедуры

// Возвращаемое значение:
//   Структура - параметры чтения сообщения обмена:
//     * НомерСообщения - Число
//     * НомерПринятого - Число
//     * Отправитель - ПланОбменаСсылка
//     * ОтправительОбъект - ПланОбменаОбъект
//     * СообщениеБылоПринятоРанее - Булево
//     * АнализДанных - Булево
//     * ВосстановленаРезервнаяКопия - Булево
//
Функция ОписаниеЧтенияСообщения()
	
	ЧтениеСообщения = Новый Структура;
	ЧтениеСообщения.Вставить("НомерСообщения");
	ЧтениеСообщения.Вставить("НомерПринятого");
	ЧтениеСообщения.Вставить("Отправитель");
	ЧтениеСообщения.Вставить("ОтправительОбъект");
	ЧтениеСообщения.Вставить("СообщениеБылоПринятоРанее");
	ЧтениеСообщения.Вставить("АнализДанных");
	ЧтениеСообщения.Вставить("ВосстановленаРезервнаяКопия");
	
	Возврат ЧтениеСообщения;
	
КонецФункции

// Параметры:
//   ЧтениеСообщения - см. ОписаниеЧтенияСообщения
//   АнализДанных - Булево
//
Процедура ПрочитатьДанныеПоОбмену(ЧтениеСообщения, АнализДанных)
	
	ПолеИмяПланаОбмена           = одАтрибут(ФайлОбмена, ТипСтрока, "ПланОбмена");
	КодОтКого                    = одАтрибут(ФайлОбмена, ТипСтрока, "ОтКого");
	ПолеНомерСообщения           = одАтрибут(ФайлОбмена, ТипЧисло,  "НомерИсходящегоСообщения");
	ПолеНомерПринятогоСообщения  = одАтрибут(ФайлОбмена, ТипЧисло,  "НомерВходящегоСообщения");
	УдалитьРегистрациюИзменений  = одАтрибут(ФайлОбмена, ТипБулево, "УдалитьРегистрациюИзменений");
	ВерсияОтправителя            = одАтрибут(ФайлОбмена, ТипСтрока, "ВерсияОтправителя");
	
	УзелОбменаПолучатель = ПланыОбмена[ИмяПланаОбмена()].НайтиПоКоду(КодОтКого);
	
	// Проверка на наличие узла получателя
	// проверка на правильность указания узла получателя в сообщении обмена.
	Если Не ЗначениеЗаполнено(УзелОбменаПолучатель)
		ИЛИ УзелОбменаПолучатель <> УзелОбменаЗагрузкаДанных Тогда
		
		СтрокаСообщения = НСтр("ru = 'Не найден узел обмена для загрузки данных. План обмена: %1, код: %2.'");
		СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ИмяПланаОбмена(), КодОтКого);
		ВызватьИсключение СтрокаСообщения;
	КонецЕсли;
	
	ЧтениеСообщения = ОписаниеЧтенияСообщения();
	ЧтениеСообщения.Отправитель       = УзелОбменаПолучатель;
	ЧтениеСообщения.ОтправительОбъект = УзелОбменаПолучатель.ПолучитьОбъект();
	ЧтениеСообщения.НомерСообщения    = ПолеНомерСообщения;
	ЧтениеСообщения.НомерПринятого    = ПолеНомерПринятогоСообщения;
	ЧтениеСообщения.СообщениеБылоПринятоРанее = Ложь;
	ЧтениеСообщения.АнализДанных = АнализДанных;
	ЧтениеСообщения.Вставить("ВосстановленаРезервнаяКопия",
		ЧтениеСообщения.НомерПринятого > ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЧтениеСообщения.Отправитель, "НомерОтправленного"));
	
	ЧтениеСообщения = Новый ФиксированнаяСтруктура(ЧтениеСообщения);
	
	Если РежимЗагрузкиДанныхВИнформационнуюБазу() Тогда
		
		НачатьТранзакцию();
		Попытка
			НомерПринятого = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЧтениеСообщения.Отправитель, "НомерПринятого");
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
		КонецПопытки;
		
		Если НомерПринятого >= ЧтениеСообщения.НомерСообщения Тогда // Номер сообщения меньше либо равен ранее принятому.
			
			ЧтениеСообщенияВременное = ОбщегоНазначения.СкопироватьРекурсивно(ЧтениеСообщения, Ложь); //Структура
			ЧтениеСообщенияВременное.СообщениеБылоПринятоРанее = Истина;
			ЧтениеСообщения = Новый ФиксированнаяСтруктура(ЧтениеСообщенияВременное);
			
			ВызватьИсключение НСтр("ru = 'Сообщение обмена было принято ранее'");
		КонецЕсли;
		
		УдалитьРегистрациюИзменений = УдалитьРегистрациюИзменений И Не ЧтениеСообщения.ВосстановленаРезервнаяКопия;
		
		Если УдалитьРегистрациюИзменений Тогда // Удаляем регистрацию изменений.
			
			Если ТранзакцияАктивна() Тогда
				ВызватьИсключение НСтр("ru = 'Удаление регистрации изменений данных не может быть выполнено в активной транзакции.'");
			КонецЕсли;
			
			ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
			
			РегистрыСведений.ИзмененияОбщихДанныхУзлов.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
			
			Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияФорматаВходящегоСообщенияОбмена(), "3.1.0.0") >= 0 Тогда
				
				РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ЗафиксироватьВыполнениеКорректировкиИнформацииСопоставления(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
				
			КонецЕсли;
			
			РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.СнятьПризнакНачальнойВыгрузкиДанных(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
			
		КонецЕсли;
		
		Если ЧтениеСообщения.ВосстановленаРезервнаяКопия Тогда
			ОбменДаннымиСервер.ПриВосстановленииРезервнойКопии(ЧтениеСообщения);
			
			ЧтениеСообщенияВременное = ОбщегоНазначения.СкопироватьРекурсивно(ЧтениеСообщения, Ложь); //Структура
			ЧтениеСообщенияВременное.ОтправительОбъект = ЧтениеСообщения.Отправитель.ПолучитьОбъект();
			ЧтениеСообщения = Новый ФиксированнаяСтруктура(ЧтениеСообщенияВременное);
		КонецЕсли;
		
		РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.УстановитьВерсиюКорреспондента(ЧтениеСообщения.Отправитель, ВерсияОтправителя);
		
	КонецЕсли;
	
	// {Обработчик: ПослеПолученияИнформацииОбУзлахОбмена} Начало
	Если Не ПустаяСтрока(Конвертация.ПослеПолученияИнформацииОбУзлахОбмена) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковЗагрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПослеПолученияИнформацииОбУзлахОбмена(ЧтениеСообщения.Отправитель);
				
			Иначе
				
				Выполнить(Конвертация.ПослеПолученияИнформацииОбУзлахОбмена);
				
			КонецЕсли;
			
		Исключение
			ВызватьИсключение ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(176,
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				НСтр("ru = 'ПослеПолученияИнформацииОбУзлахОбмена (конвертация)'"));
		КонецПопытки;
		
	КонецЕсли;
	// {Обработчик: ПослеПолученияИнформацииОбУзлахОбмена} Окончание
	
КонецПроцедуры

Процедура ПрочитатьОбщиеДанныеУзлов(ЧтениеСообщения)
	
	ФайлОбмена.Прочитать();
	
	РежимЗагрузкиДанныхПредыдущий = РежимЗагрузкиДанных;
	
	РежимЗагрузкиДанных = "ЗагрузкаВТаблицуЗначений";
	
	ОбщийУзел = ПрочитатьОбъект();
	
	УвеличитьСчетчикЗагруженныхОбъектов();
	
	РежимЗагрузкиДанных = РежимЗагрузкиДанныхПредыдущий;
	
	// {Обработчик: ПриПолученииДанныхОтправителя} Начало
	Игнорировать = Ложь;
	ИмяПланаОбмена = ОбщийУзел.Метаданные().Имя;
	Если ОбменДаннымиСервер.ЕстьАлгоритмМенеджераПланаОбмена("ПриПолученииДанныхОтправителя",ИмяПланаОбмена) Тогда
		ПланыОбмена[ИмяПланаОбмена].ПриПолученииДанныхОтправителя(ОбщийУзел, Игнорировать);
	
		Если Игнорировать = Истина Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
	// {Обработчик: ПриПолученииДанныхОтправителя} Окончание
	
	Если ОбменДаннымиСобытия.ДанныеРазличаются(ОбщийУзел, ОбщийУзел.Ссылка.ПолучитьОбъект()) Тогда
		
		НачатьТранзакцию();
		Попытка
			
			ОбщийУзел.ОбменДанными.Загрузка = Истина;
			ОбщийУзел.Записать();
			
			// Обновляем повторно используемые значения механизма.
			ОбменДаннымиСлужебный.СброситьКэшМеханизмаРегистрацииОбъектов();
			
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			ВызватьИсключение;
		КонецПопытки;
		
		// Если существует открытая транзакция
		// (открытая при получении данных в режиме "Загрузка") ее необходимо закрыть.
		// Если транзакция не будет закрыта, то блокировка,
		// накладываемая на регистр "ИзмененияОбщихДанныхУзлов"
		// при вызове метода "УдалитьРегистрациюИзменений" будет действовать 
		// до завершения открытой транзакции (окончание получения данных),
		// что сделает невозможным как интерактивное изменение узла плана обмена,
		// так и программное из других сеансов информационной базы.
		ОткрытьТранзакцию = Ложь;
		Если ТранзакцияАктивна() Тогда
			ЗафиксироватьТранзакцию();
			ОткрытьТранзакцию = Истина;
		КонецЕсли;
		
		// Удаляем регистрацию изменений на случай, если изменения были ранее зарегистрированы (в случае коллизии изменений).
		РегистрыСведений.ИзмененияОбщихДанныхУзлов.УдалитьРегистрациюИзменений(ОбщийУзел.Ссылка);
		
		// Если до вызова метода «УдалитьРегистрациюИзменений» регистра сведений «ИзмененияОбщихДанныхУзлов»
		// была закрыта транзакция, открытая при получении данных в режиме "Загрузка", то ее необходимо открыть заново.
		Если ОткрытьТранзакцию Тогда
			НачатьТранзакцию();
		КонецЕсли;
		
		Если ЧтениеСообщения <> Неопределено
			И ОбщийУзел.Ссылка = ЧтениеСообщения.Отправитель Тогда
			
			ЧтениеСообщенияВременное = ОбщегоНазначения.СкопироватьРекурсивно(ЧтениеСообщения, Ложь);
			ЧтениеСообщенияВременное.ОтправительОбъект = ЧтениеСообщения.Отправитель.ПолучитьОбъект();
			ЧтениеСообщения = Новый ФиксированнаяСтруктура(ЧтениеСообщенияВременное);
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ВыполнитьОтложенноеПроведениеДокументов()
	
	ОбменДаннымиСервер.ВыполнитьОтложенноеПроведениеДокументов(
		ДокументыДляОтложенногоПроведения(), УзелОбменаЗагрузкаДанных, ДополнительныеСвойстваДляОтложенногоПроведения());
		
КонецПроцедуры

Процедура ВыполнитьОтложеннуюЗаписьОбъектов()
	
	ОбменДаннымиСервер.ВыполнитьОтложеннуюЗаписьОбъектов(
		ОбъектыДляОтложеннойЗаписи(), УзелОбменаЗагрузкаДанных);
	
КонецПроцедуры

Процедура ЗаписатьИнформациюОбОбменеДаннымиЧерезПланыОбмена(Знач НомерОтправленного)
	
	Приемник = СоздатьУзел("ДанныеПоОбмену");
	
	УстановитьАтрибут(Приемник, "ПланОбмена", ИмяПланаОбмена());
	УстановитьАтрибут(Приемник, "Кому", ОбменДаннымиСервер.ИдентификаторУзлаКорреспондентаДляОбмена(УзелДляОбмена));
	УстановитьАтрибут(Приемник, "ОтКого", ОбменДаннымиСервер.ИдентификаторЭтогоУзлаДляОбмена(УзелДляОбмена));
	
	// Атрибуты механизма квитирования сообщений обмена.
	УстановитьАтрибут(Приемник, "НомерИсходящегоСообщения", НомерОтправленного);
	УстановитьАтрибут(Приемник, "НомерВходящегоСообщения",  УзелДляОбмена.НомерПринятого);
	УстановитьАтрибут(Приемник, "УдалитьРегистрациюИзменений", Истина);
	
	УстановитьАтрибут(Приемник, "ВерсияОтправителя", СокрЛП(Метаданные.Версия));
	
	// Запись объекта в файл
	Приемник.ЗаписатьКонецЭлемента();
	
	ЗаписатьВФайл(Приемник);
	
КонецПроцедуры

Процедура ВыгрузитьОбщиеДанныеУзлов(Знач НомерОтправленного)
	
	ВыборкаИзмененийУзлов = РегистрыСведений.ИзмененияОбщихДанныхУзлов.ВыбратьИзменения(УзелДляОбмена, НомерОтправленного);
	
	Если ВыборкаИзмененийУзлов.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелДляОбмена);
	
	ОбщиеДанныеУзлов = ОбменДаннымиПовтИсп.ОбщиеДанныеУзлов(УзелДляОбмена);
	
	Если ПустаяСтрока(ОбщиеДанныеУзлов) Тогда
		Возврат;
	КонецЕсли;
	
	ПравилаКонвертацииСвойств = Новый ТаблицаЗначений; // см. КоллекцияПравилаКонвертацииСвойств
	ИнициализацияТаблицыПравилКонвертацииСвойств(ПравилаКонвертацииСвойств);
	
	Свойства       = ПравилаКонвертацииСвойств.Скопировать(); // см. КоллекцияПравилаКонвертацииСвойств
	СвойстваПоиска = ПравилаКонвертацииСвойств.Скопировать(); // см. КоллекцияПравилаКонвертацииСвойств
	
	МетаданныеОбщегоУзла = Метаданные.ПланыОбмена[ИмяПланаОбмена];
	
	ТабличныеЧастиОбщегоУзла = ОбменДаннымиСобытия.ТабличныеЧастиОбъекта(МетаданныеОбщегоУзла);
	
	СвойстваОбщегоУзла = СтрРазделить(ОбщиеДанныеУзлов, ",");
	
	Для Каждого Свойство Из СвойстваОбщегоУзла Цикл
		
		Если ТабличныеЧастиОбщегоУзла.Найти(Свойство) <> Неопределено Тогда
			
			ПКС = Свойства.Добавить();
			ПКС.ЭтоГруппа = Истина;
			ПКС.ВидИсточника = "ТабличнаяЧасть";
			ПКС.ВидПриемника = "ТабличнаяЧасть";
			ПКС.Источник = Свойство;
			ПКС.Приемник = Свойство;
			
			ТаблицаПКГС = ПравилаКонвертацииСвойств.Скопировать(); // см. КоллекцияПравилаКонвертацииСвойств
			
			МетаданныеТЧ = МетаданныеОбщегоУзла.ТабличныеЧасти[Свойство]; // ОбъектМетаданныхТабличнаяЧасть
			
			Для Каждого Реквизит Из МетаданныеТЧ.Реквизиты Цикл
				
				ИмяРеквизита = Реквизит.Имя;
				
				ПКГС = ТаблицаПКГС.Добавить();
				ПКГС.ЭтоГруппа = Ложь;
				ПКГС.ВидИсточника = "Реквизит";
				ПКГС.ВидПриемника = "Реквизит";
				ПКГС.Источник = ИмяРеквизита;
				ПКГС.Приемник = ИмяРеквизита;
				
			КонецЦикла;
			
			ПКС.ПравилаГруппы = ТаблицаПКГС;
			
		Иначе
			
			ПКС = Свойства.Добавить();
			ПКС.ЭтоГруппа = Ложь;
			ПКС.ВидИсточника = "Реквизит";
			ПКС.ВидПриемника = "Реквизит";
			ПКС.Источник = Свойство;
			ПКС.Приемник = Свойство;
			
		КонецЕсли;
		
	КонецЦикла;
	
	ПКС = СвойстваПоиска.Добавить();
	ПКС.ВидИсточника = "Свойство";
	ПКС.ВидПриемника = "Свойство";
	ПКС.Источник = "Код";
	ПКС.Приемник = "Код";
	ПКС.ТипИсточника = "Строка";
	ПКС.ТипПриемника = "Строка";
	
	ПКО = КоллекцияПравилаКонвертации().Добавить();
	ПКО.СинхронизироватьПоИдентификатору = Ложь;
	ПКО.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли = Ложь;
	ПКО.НеВыгружатьОбъектыСвойствПоСсылкам = Истина;
	ПКО.ТипИсточника = "ПланОбменаСсылка." + ИмяПланаОбмена;
	ПКО.Источник = Тип(ПКО.ТипИсточника);
	ПКО.ТипПриемника = ПКО.ТипИсточника;
	ПКО.Приемник     = ПКО.ТипИсточника;
	
	ПКО.Свойства = Свойства;
	ПКО.СвойстваПоиска = СвойстваПоиска;
	
	ОбщийУзел = ПланыОбмена[ИмяПланаОбмена].СоздатьУзел();
	ОбменДаннымиСобытия.ЗаполнитьЗначенияСвойствОбъекта(ОбщийУзел, УзелДляОбмена.ПолучитьОбъект(), ОбщиеДанныеУзлов);
	
	// {Обработчик: ПриОтправкеДанныхОтправителя} Начало
	Игнорировать = Ложь;
	Если ОбменДаннымиСервер.ЕстьАлгоритмМенеджераПланаОбмена("ПриОтправкеДанныхОтправителя", ИмяПланаОбмена) Тогда
		ПланыОбмена[ИмяПланаОбмена].ПриОтправкеДанныхОтправителя(ОбщийУзел, Игнорировать);
		Если Игнорировать = Истина Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
	// {Обработчик: ПриОтправкеДанныхОтправителя} Окончание
	
	ОбщийУзел.Код = ОбменДаннымиСервер.ИдентификаторЭтогоУзлаДляОбмена(УзелДляОбмена);
	
	УзелXML = СоздатьУзел("ОбщиеДанныеУзлов");
	
	ВыгрузитьПоПравилу(ОбщийУзел,,,,,,, ПКО,,, УзелXML);
	
	УзелXML.ЗаписатьКонецЭлемента();
	
	ЗаписатьВФайл(УзелXML);
	
КонецПроцедуры

Функция ВыгрузитьДанныеСсылочногоОбъекта(Значение, ИсходящиеДанные, ИмяПКО, ПКОСвойств, ТипПриемника, УзелСвойства, Знач ВыгрузитьТолькоСсылку)
	
	ЭтоПравилоСГлобальнойВыгрузкой = Ложь;
	УзелСсылки    = ВыгрузитьПоПравилу(Значение, , ИсходящиеДанные, , ИмяПКО, , ВыгрузитьТолькоСсылку, ПКОСвойств, ЭтоПравилоСГлобальнойВыгрузкой, , , , Ложь);
	ТипУзлаСсылки = ТипЗнч(УзелСсылки);

	Если ПустаяСтрока(ТипПриемника) Тогда
				
		ТипПриемника  = ПКОСвойств.Приемник;
		УстановитьАтрибут(УзелСвойства, "Тип", ТипПриемника);
				
	КонецЕсли;
			
	Если УзелСсылки = Неопределено Тогда
				
		Возврат Неопределено;
				
	КонецЕсли;
				
	ДобавитьСвойстваДляВыгрузки(УзелСсылки, ТипУзлаСсылки, УзелСвойства, ЭтоПравилоСГлобальнойВыгрузкой);	
	
	Возврат УзелСсылки;
	
КонецФункции

Процедура ПередатьОдинПараметрВПриемник(Имя, ИсходноеЗначениеПараметра, ПравилоКонвертации = "")
	
	Если ПустаяСтрока(ПравилоКонвертации) Тогда
		
		УзелПараметра = СоздатьУзел("ЗначениеПараметра");
		
		УстановитьАтрибут(УзелПараметра, "Имя", Имя);
		УстановитьАтрибут(УзелПараметра, "Тип", одТипЗначенияСтрокой(ИсходноеЗначениеПараметра));
		
		ЭтоNULL = Ложь;
		Пусто = одПустое(ИсходноеЗначениеПараметра, ЭтоNULL);
		
		Если Пусто Тогда
			
			// Надо записать что это пустое значение.
			одЗаписатьЭлемент(УзелПараметра, "Пусто");
			
			УзелПараметра.ЗаписатьКонецЭлемента();
			
			ЗаписатьВФайл(УзелПараметра);
			
			Возврат;
			
		КонецЕсли;
		
		одЗаписатьЭлемент(УзелПараметра, "Значение", ИсходноеЗначениеПараметра);
		
		УзелПараметра.ЗаписатьКонецЭлемента();
		
		ЗаписатьВФайл(УзелПараметра);
		
	Иначе
		
		УзелПараметра = СоздатьУзел("ЗначениеПараметра");
		
		УстановитьАтрибут(УзелПараметра, "Имя", Имя);
		
		ЭтоNULL = Ложь;
		Пусто = одПустое(ИсходноеЗначениеПараметра, ЭтоNULL);
		
		Если Пусто Тогда
			
			ПКОСвойств = НайтиПравило(ИсходноеЗначениеПараметра, ПравилоКонвертации);
			ТипПриемника  = ПКОСвойств.Приемник;
			УстановитьАтрибут(УзелПараметра, "Тип", ТипПриемника);
			
			// Надо записать что это пустое значение.
			одЗаписатьЭлемент(УзелПараметра, "Пусто");
			
			УзелПараметра.ЗаписатьКонецЭлемента();
			
			ЗаписатьВФайл(УзелПараметра);
			
			Возврат;
			
		КонецЕсли;
		
		ВыгрузитьДанныеСсылочногоОбъекта(ИсходноеЗначениеПараметра, Неопределено, ПравилоКонвертации, Неопределено, Неопределено, УзелПараметра, Истина);
		
		УзелПараметра.ЗаписатьКонецЭлемента();
		
		ЗаписатьВФайл(УзелПараметра);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ПередатьДополнительныеПараметрыВПриемник()
	
	Для Каждого Параметр Из ТаблицаНастройкиПараметров Цикл
		
		Если Параметр.ПередаватьПараметрПриВыгрузке = Истина Тогда
			
			ПередатьОдинПараметрВПриемник(Параметр.Имя, Параметр.Значение, Параметр.ПравилоКонвертации);
					
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПередатьИнформациюОТипахВПриемник()
	
	Если Не ПустаяСтрока(СтрокаТиповДляПриемника) Тогда
		ЗаписатьВФайл(СтрокаТиповДляПриемника);
	КонецЕсли;
		
КонецПроцедуры

Процедура ПередатьИнформациюОПользовательскихПоляхПоискаВПриемник()
	
	Для Каждого КлючИЗначенияСопоставления Из ИнформацияОПользовательскихПоляхПоискаПриВыгрузкеДанных Цикл
		
		УзелПараметра = СоздатьУзел("НастройкаПользовательскогоПоиска");
		
		одЗаписатьЭлемент(УзелПараметра, "ИмяПравила", КлючИЗначенияСопоставления.Ключ);
		одЗаписатьЭлемент(УзелПараметра, "НастройкаПоиска", КлючИЗначенияСопоставления.Значение);
		
		УзелПараметра.ЗаписатьКонецЭлемента();
		ЗаписатьВФайл(УзелПараметра);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных()
	
	КомментарийПриВыгрузкеДанных = "";
	КомментарийПриЗагрузкеДанных = "";
	
КонецПроцедуры

Процедура ВыгруженныеПоСсылкеОбъектыДобавитьЗначение(Значение)
	
	Если ВыгруженныеПоСсылкеОбъекты().Найти(Значение) = Неопределено Тогда
		
		ВыгруженныеПоСсылкеОбъекты().Добавить(Значение);
		
	КонецЕсли;
	
КонецПроцедуры

Функция ОбъектПроходитФильтрРазрешенныхОбъектов(Значение)
	
	Возврат РегистрыСведений.СоответствияОбъектовИнформационныхБаз.ОбъектЕстьВРегистре(Значение, УзелДляОбмена);
	
КонецФункции

Функция ПоляПоискаМеханизмаСопоставленияОбъектов(Знач ПоляПоиска)
	
	ПоляПоискаКоллекция = СтрРазделить(ПоляПоиска, ",");
	
	ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(ПоляПоискаКоллекция, "ЭтоГруппа");
	
	Возврат СтрСоединить(ПоляПоискаКоллекция, ",");
КонецФункции

Процедура ВыполнитьВыгрузку(СтрокаСообщенияОбОшибке = "")
	
	ПолеИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелДляОбмена);
	
	ВыгрузитьИнформациюСопоставления = ВыгрузитьИнформациюСопоставленияОбъектов(УзелДляОбмена);
	
	ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных();
	
	ТекущийУровеньВложенностиВыгрузитьПоПравилу = 0;
	
	СтекВызововВыгрузкиДанных = Новый ТаблицаЗначений;
	СтекВызововВыгрузкиДанных.Колонки.Добавить("Ссылка");
	СтекВызововВыгрузкиДанных.Индексы.Добавить("Ссылка");
	
	ИнициализироватьМенеджерыИСообщения();
	
	ПолеСчетчикВыгруженныхОбъектов = Неопределено;
	СчетчикНПП 				= 0;
	НППЗаписанногоВФайл		= 0;
	
	Для Каждого Правило Из ТаблицаПравилКонвертации Цикл
		
		Правило.Выгруженные = СоздатьТаблицуВыгруженныхОбъектов();
		
	КонецЦикла;
	
	// Получаем типы объектов метаданных, которые будут участвовать в выгрузке.
	ТаблицаПравилВыгрузкиИспользуемые = КоллекцияПравилаВыгрузкиДанных().Скопировать(Новый Структура("Включить", Истина));
	ТаблицаПравилВыгрузкиИспользуемые.Индексы.Добавить("ОбъектВыборкиМетаданные");
	
	Для Каждого СтрокаТаблицы Из ТаблицаПравилВыгрузкиИспользуемые Цикл
		
		Если Не СтрокаТаблицы.ОбъектВыборки = Тип("КонстантыНабор") Тогда
			
			СтрокаТаблицы.ОбъектВыборкиМетаданные = Метаданные.НайтиПоТипу(СтрокаТаблицы.ОбъектВыборки);
			
		КонецЕсли;
		
	КонецЦикла;
	
	СоответствиеДанныхДляОбновленияВыгруженныхЭлементов = Новый Соответствие;
	
	// {ОБРАБОТЧИК ПередВыгрузкойДанных}
	Отказ = Ложь;
	
	Если Не ПустаяСтрока(Конвертация.ПередВыгрузкойДанных) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПередВыгрузкойДанных(ФайлОбмена, Отказ);
				
			Иначе
				
				Выполнить(Конвертация.ПередВыгрузкойДанных);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(62, 
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				НСтр("ru = 'ПередВыгрузкойДанных (конвертация)'"));
				
			Отказ = Истина;
		КонецПопытки; 
		
		Если Отказ Тогда // Отказ от выгрузки данных
			ЗавершитьВедениеПротоколаОбмена();
			Возврат;
		КонецЕсли;
		
	КонецЕсли;
	// {ОБРАБОТЧИК ПередВыгрузкойДанных}
	
	ПередатьИнформациюОПользовательскихПоляхПоискаВПриемник();
	
	ПередатьИнформациюОТипахВПриемник();
	
	// Передаем доп. параметры в приемник.
	ПередатьДополнительныеПараметрыВПриемник();
	
	ТекстСобытияПослеЗагрузкиПараметров = "";
	Если Конвертация.Свойство("ПослеЗагрузкиПараметров", ТекстСобытияПослеЗагрузкиПараметров)
		И Не ПустаяСтрока(ТекстСобытияПослеЗагрузкиПараметров) Тогда
		
		ЗаписьСобытия = Новый ЗаписьXML;
		ЗаписьСобытия.УстановитьСтроку();
		одЗаписатьЭлемент(ЗаписьСобытия, "АлгоритмПослеЗагрузкиПараметров", ТекстСобытияПослеЗагрузкиПараметров);
		
		ЗаписатьВФайл(ЗаписьСобытия);
		
	КонецЕсли;
	
	НомерОтправленного = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УзелДляОбмена, "НомерОтправленного") + ?(ВыгрузитьИнформациюСопоставления, 2, 1);
	
	ЗаписатьИнформациюОбОбменеДаннымиЧерезПланыОбмена(НомерОтправленного);
	
	ВыгрузитьОбщиеДанныеУзлов(НомерОтправленного);
	
	Отказ = Ложь;
	
	// ВЫПОЛНЯЕМ ВЫГРУЗКУ РЕГИСТРА СОПОСТАВЛЕНИЯ
	Если ВыгрузитьИнформациюСопоставления Тогда
		
		ЗаписьXML = Новый ЗаписьXML;
		ЗаписьXML.УстановитьСтроку();
		ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
		ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелДляОбмена);
		
		Попытка
			ВыполнитьВыгрузкуРегистраСопоставленияОбъектов(ЗаписьСообщения, СтрокаСообщенияОбОшибке);
		Исключение
			Отказ = Истина;
		КонецПопытки;
		
		Если Отказ Тогда
			ЗаписьСообщения.ПрерватьЗапись();
		Иначе
			ЗаписьСообщения.ЗакончитьЗапись();
		КонецЕсли;
		
		ЗаписьXML.Закрыть();
		ЗаписьXML = Неопределено;
		
		Если Отказ Тогда
			Возврат;
		КонецЕсли;
		
	КонецЕсли;
	
	// ВЫПОЛНЯЕМ ВЫГРУЗКУ КОРРЕКТИРОВКИ РЕГИСТРА СОПОСТАВЛЕНИЯ
	Если НеобходимоВыполнитьКорректировкуИнформацииСопоставления() Тогда
		
		ВыгрузитьКорректировкуИнформацииСопоставления();
		
	КонецЕсли;
	
	// ВЫПОЛНЯЕМ ВЫГРУЗКУ ЗАРЕГИСТРИРОВАННЫХ ДАННЫХ
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
	ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелДляОбмена);
	
	Попытка
		ВыполнитьВыгрузкуЗарегистрированныхДанных(ЗаписьСообщения, СтрокаСообщенияОбОшибке, ТаблицаПравилВыгрузкиИспользуемые);
	Исключение
		Отказ = Истина;
		ЗаписатьВПротоколВыполнения(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	КонецПопытки;
	
	// Выполняем регистрацию объектов на текущем узле, которые были выгружены по ссылке.
	Для Каждого Элемент Из ВыгруженныеПоСсылкеОбъекты() Цикл
		
		ПланыОбмена.ЗарегистрироватьИзменения(ЗаписьСообщения.Получатель, Элемент);
		
	КонецЦикла;
	
	// Назначаем номер отправленного сообщения для объектов, выгруженных по ссылке.
	Если ВыгруженныеПоСсылкеОбъекты().Количество() > 0 Тогда
		
		ОбменДаннымиСервер.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, ВыгруженныеПоСсылкеОбъекты());
		
	КонецЕсли;
	
	// Назначаем номер отправленного сообщения для объектов, созданных в текущей сессии выгрузки данных.
	Если СозданныеПриВыгрузкеОбъекты().Количество() > 0 Тогда
		
		ОбменДаннымиСервер.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, СозданныеПриВыгрузкеОбъекты());
		
	КонецЕсли;
	
	Если Отказ Тогда
		ЗаписьСообщения.ПрерватьЗапись();
	Иначе
		ЗаписьСообщения.ЗакончитьЗапись();
	КонецЕсли;
	
	ЗаписьXML.Закрыть();
	ЗаписьXML = Неопределено;
	
	// {ОБРАБОТЧИК ПослеВыгрузкиДанных}
	Если Не Отказ И Не ПустаяСтрока(Конвертация.ПослеВыгрузкиДанных) Тогда
		
		Попытка
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПослеВыгрузкиДанных(ФайлОбмена);
				
			Иначе
				
				Выполнить(Конвертация.ПослеВыгрузкиДанных);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(63,
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), НСтр("ru = 'ПослеВыгрузкиДанных (конвертация)'"));
		КонецПопытки;
	
	КонецЕсли;
	// {ОБРАБОТЧИК ПослеВыгрузкиДанных}
	
КонецПроцедуры

Процедура ВыполнитьВыгрузкуРегистраСопоставленияОбъектов(ЗаписьСообщения, СтрокаСообщенияОбОшибке)
	
	// Выбираем изменения только для регистра сопоставления.
	ВыборкаИзменений = ОбменДаннымиСервер.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, Метаданные.РегистрыСведений.СоответствияОбъектовИнформационныхБаз);
	
	Пока ВыборкаИзменений.Следующий() Цикл
		
		Данные = ВыборкаИзменений.Получить();
		
		// Накладываем фильтр на выгрузку данных.
		Если Данные.Отбор.УзелИнформационнойБазы.Значение <> УзелДляОбмена Тогда
			Продолжить;
		ИначеЕсли ПустаяСтрока(Данные.Отбор.УникальныйИдентификаторПриемника.Значение) Тогда
			Продолжить;
		КонецЕсли;
		
		ВыгружатьОбъект = Истина;
		
		Для Каждого Запись Из Данные Цикл
			
			Если ВыгружатьОбъект И Запись.ОбъектВыгруженПоСсылке = Истина Тогда
				
				ВыгружатьОбъект = Ложь;
				
			КонецЕсли;
			
		КонецЦикла;
		
		// Выгружаем зарегистрированную информацию РС СоответствияОбъектовИнформационныхБаз;
		// правила конвертации РС прописаны в коде этой обработки;
		Если ВыгружатьОбъект Тогда
			
			ВыгрузитьИнформациюОЗарегистрированномОбъекте(Данные);
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ВыполнитьВыгрузкуЗарегистрированныхДанных(ЗаписьСообщения, СтрокаСообщенияОбОшибке, ТаблицаПравилВыгрузкиИспользуемые)
	
	// Переменные-заглушки для поддержки механизма отладки кода обработчиков событий.
	Перем Отказ, ИмяПКО, ВыборкаДанных, ИсходящиеДанные;
	// {ОБРАБОТЧИК ПередПолучениемИзмененныхОбъектов}
	Если Не ПустаяСтрока(Конвертация.ПередПолучениемИзмененныхОбъектов) Тогда
		
		Попытка
			
			Получатель = УзелДляОбмена;
			
			Если ОтладкаОбработчиковВыгрузки Тогда
				
				ВыполнитьОбработчик_Конвертация_ПередПолучениемИзмененныхОбъектов(Получатель, УзелДляФоновогоОбмена);
				
			Иначе
				
				Выполнить(Конвертация.ПередПолучениемИзмененныхОбъектов);
				
			КонецЕсли;
			
		Исключение
			ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(175, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
				НСтр("ru = 'ПередПолучениемИзмененныхОбъектов (конвертация)'"));
			Возврат;
		КонецПопытки;
		
	КонецЕсли;
	// {ОБРАБОТЧИК ПередПолучениемИзмененныхОбъектов}
	
	МассивВыгружаемыхМетаданных = ТаблицаПравилВыгрузкиИспользуемые.ВыгрузитьКолонку("ОбъектВыборкиМетаданные");
	
	// Значение "Неопределено" свидетельствует о необходимости выгрузки констант.
	Если МассивВыгружаемыхМетаданных.Найти(Неопределено) <> Неопределено Тогда
		
		ДополнитьМассивВыгружаемыхМетаданныхКонстантами(МассивВыгружаемыхМетаданных);
		
	КонецЕсли;
	
	// Удаляем из массива элементы со значением "Неопределено".
	УдалитьНедопустимыеЗначенияИзМассиваВыгружаемыхМетаданных(МассивВыгружаемыхМетаданных);
	
	// Регистр сведений СоответствияОбъектовИнформационныхБаз выгружается отдельно, поэтому в эту выборку он не должен
	// входить.
	Если МассивВыгружаемыхМетаданных.Найти(Метаданные.РегистрыСведений.СоответствияОбъектовИнформационныхБаз) <> Неопределено Тогда
		
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(МассивВыгружаемыхМетаданных, Метаданные.РегистрыСведений.СоответствияОбъектовИнформационныхБаз);
		
	КонецЕсли;
	
	// Обновляем повторно используемые значения МРО.
	ОбменДаннымиСлужебный.ПроверитьКэшМеханизмаРегистрацииОбъектов();
	
	НачальнаяВыгрузкаДанных = ОбменДаннымиСервер.УстановленПризнакНачальнойВыгрузкиДанных(ЗаписьСообщения.Получатель);
	
	// ВЫБОРКА ИЗМЕНЕНИЙ
	ВыборкаИзменений = ОбменДаннымиСервер.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, МассивВыгружаемыхМетаданных);
	
	ОбъектМетаданныхПредыдущий      = Неопределено;
	ПравилоВыгрузкиДанныхПредыдущее = Неопределено;
	ПравилоВыгрузкиДанных           = Неопределено;
	ВыгружаетсяРегистр              = Ложь;
	ВыгружаютсяКонстанты            = Ложь;
	
	ЭтоОбменЧерезВнешнееСоединение = ЭтоОбменЧерезВнешнееСоединение();
	
	НачатьТранзакциюПриЗагрузкеДанных();
	Попытка
		УзелДляОбменаОбъект = УзелДляОбмена.ПолучитьОбъект();
		
		Пока ВыборкаИзменений.Следующий() Цикл
			Инкремент(КоличествоОбъектовКВыгрузке);
		КонецЦикла;
		
		ВыборкаИзменений.Сбросить();
		
		ЕстьПолеСчетчикЗагруженныхОбъектовВнешнееСоединение = Ложь;
		Если ЭтоОбменЧерезВнешнееСоединение() Тогда
			РеквизитыОбработкиЗагрузки = ОбработкаДляЗагрузкиДанных().Метаданные().Реквизиты;
			// В базе-корреспонденте может не быть этого реквизита обработки.
			Если РеквизитыОбработкиЗагрузки.Найти("КоличествоОбъектовКЗагрузкеВнешнееСоединение") <> Неопределено Тогда
				ОбработкаДляЗагрузкиДанных().КоличествоОбъектовКЗагрузкеВнешнееСоединение = КоличествоОбъектовКВыгрузке;
			КонецЕсли;
			ЕстьПолеСчетчикЗагруженныхОбъектовВнешнееСоединение = РеквизитыОбработкиЗагрузки.Найти("СчетчикЗагруженныхОбъектовВнешнееСоединение") <> Неопределено;
		КонецЕсли;
		
		Пока ВыборкаИзменений.Следующий() Цикл
			
			Если ЭтоОбменЧерезВнешнееСоединение() Тогда
				// В базе-корреспонденте может не быть этого реквизита обработки.
				Если ЕстьПолеСчетчикЗагруженныхОбъектовВнешнееСоединение Тогда
					Инкремент(ОбработкаДляЗагрузкиДанных().СчетчикЗагруженныхОбъектовВнешнееСоединение);
				КонецЕсли;
			КонецЕсли;
			Инкремент(ПолеСчетчикВыгруженныхОбъектов);
			
			ОбменДаннымиСервер.РассчитатьПроцентВыгрузки(СчетчикВыгруженныхОбъектов(), КоличествоОбъектовКВыгрузке);
			
			Данные = ВыборкаИзменений.Получить();
			
			ТипДанныхДляВыгрузки = ТипЗнч(Данные);
			
			// Отрабатываем удаление объекта.
			Если ТипДанныхДляВыгрузки = ТипУдалениеОбъекта Тогда
				
				ОтработатьУдалениеОбъекта(Данные);
				Продолжить;
				
			ИначеЕсли ТипДанныхДляВыгрузки = ТипРегистрСоответствия Тогда
				Продолжить;
			КонецЕсли;
			
			ОбъектМетаданныхТекущий = Данные.Метаданные(); // ОбъектМетаданных
			
			// Выгружается новый тип объекта метаданных.
			Если ОбъектМетаданныхПредыдущий <> ОбъектМетаданныхТекущий Тогда
				
				Если ОбъектМетаданныхПредыдущий <> Неопределено Тогда
					
					// {ОБРАБОТЧИК ПослеОбработки ПВД}
					Если ПравилоВыгрузкиДанныхПредыдущее <> Неопределено
						И Не ПустаяСтрока(ПравилоВыгрузкиДанныхПредыдущее.ПослеОбработки) Тогда
						
						Попытка
							
							Если ОтладкаОбработчиковВыгрузки Тогда
								
								ВыполнитьОбработчик_ПВД_ПослеОбработкиПравила(ИмяПКО, ПравилоВыгрузкиДанныхПредыдущее, ИсходящиеДанные);
								
							Иначе
								
								Выполнить(ПравилоВыгрузкиДанныхПредыдущее.ПослеОбработки);
								
							КонецЕсли;
							
						Исключение
							ЗаписатьИнформациюОбОшибкеОбработчикиПВД(32, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
								ПравилоВыгрузкиДанныхПредыдущее["Имя"], "ПослеОбработкиВыгрузкиДанных");
						КонецПопытки;
						
					КонецЕсли;
					// {ОБРАБОТЧИК ПослеОбработки ПВД}
					
				КонецЕсли;
				
				ОбъектМетаданныхПредыдущий = ОбъектМетаданныхТекущий;
				
				ВыгружаетсяРегистр = Ложь;
				ВыгружаютсяКонстанты = Ложь;
				
				СтруктураДанных = МенеджерыДляПлановОбмена[ОбъектМетаданныхТекущий];
				
				Если СтруктураДанных = Неопределено Тогда
					
					ВыгружаютсяКонстанты = Метаданные.Константы.Содержит(ОбъектМетаданныхТекущий);
					
				ИначеЕсли СтруктураДанных.ЭтоРегистр = Истина Тогда
					
					ВыгружаетсяРегистр = Истина;
					
				КонецЕсли;
				
				Если ВыгружаютсяКонстанты Тогда
					
					ПравилоВыгрузкиДанных = ТаблицаПравилВыгрузкиИспользуемые.Найти(Тип("КонстантыНабор"), "ОбъектВыборкиМетаданные");
					Если ПравилоВыгрузкиДанных = Неопределено Тогда
						 
						 ПравилоВыгрузкиДанных = ТаблицаПравилВыгрузкиИспользуемые.Найти(Тип("КонстантыНабор"), "ОбъектВыборки");
						 
					КонецЕсли;
					
				Иначе
					
					ПравилоВыгрузкиДанных = ТаблицаПравилВыгрузкиИспользуемые.Найти(ОбъектМетаданныхТекущий, "ОбъектВыборкиМетаданные");
					
				КонецЕсли;
				
				ПравилоВыгрузкиДанныхПредыдущее = ПравилоВыгрузкиДанных;
				
				// {ОБРАБОТЧИК ПередОбработкой ПВД}
				ИсходящиеДанные = Неопределено;
				
				Если ПравилоВыгрузкиДанных <> Неопределено
					И Не ПустаяСтрока(ПравилоВыгрузкиДанных.ПередОбработкой) Тогда
					
					Попытка
						
						Если ОтладкаОбработчиковВыгрузки Тогда
							
							ВыполнитьОбработчик_ПВД_ПередОбработкойПравила(Отказ, ИмяПКО, ПравилоВыгрузкиДанных, ИсходящиеДанные, ВыборкаДанных);
							
						Иначе
							
							Выполнить(ПравилоВыгрузкиДанных.ПередОбработкой);
							
						КонецЕсли;
						
					Исключение
						ЗаписатьИнформациюОбОшибкеОбработчикиПВД(31, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
							ПравилоВыгрузкиДанных.Имя, "ПередОбработкойВыгрузкиДанных");
					КонецПопытки;
					
					
				КонецЕсли;
				// {ОБРАБОТЧИК ПередОбработкой ПВД}
				
			КонецЕсли;
			
			Если ТипДанныхДляВыгрузки <> ТипРегистрСоответствия Тогда
				
				// Определяем вид отправки объекта.
				ОтправкаЭлемента = ОтправкаЭлементаДанных.Авто;
				
				СтандартныеПодсистемыСервер.ПриОтправкеДанныхПодчиненному(Данные, ОтправкаЭлемента, НачальнаяВыгрузкаДанных, УзелДляОбменаОбъект);
				
				Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить Тогда
					
					Если ВыгружаетсяРегистр Тогда
						
						// Удаление регистра отсылаем в виде пустого набора записей.
						
					Иначе
						
						// Посылаем информацию об удалении.
						ОтработатьУдалениеОбъекта(Данные);
						Продолжить;
						
					КонецЕсли;
					
				ИначеЕсли ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда
					
					Продолжить;
					
				КонецЕсли;
				
			КонецЕсли;
			
			// ВЫГРУЗКА ОБЪЕКТА
			Если ВыгружаетсяРегистр Тогда
				
				// выгрузка регистра
				ВыгрузкаРегистра(Данные, ПравилоВыгрузкиДанных, ИсходящиеДанные, НеВыгружатьОбъектыПоСсылкам);
				
			ИначеЕсли ВыгружаютсяКонстанты Тогда
				
				// выгрузка набора констант
				Свойства = Менеджеры[Тип("КонстантыНабор")];
				
				ВыгрузитьНаборКонстант(ПравилоВыгрузкиДанных, Свойства, ИсходящиеДанные, ОбъектМетаданныхТекущий.Имя);
				
			Иначе
				
				Попытка
					
					СсылкаДляПереходаПриВозникновенииОшибки = Данные.Ссылка;
					
				Исключение
					
					Если Ложь Тогда // Для работы АПК
						
						ВызватьИсключение;
						
					КонецЕсли;
					
				КонецПопытки;
				
				// выгрузка ссылочных типов
				ВыгрузкаОбъектаВыборки(Данные, ПравилоВыгрузкиДанных, , ИсходящиеДанные, НеВыгружатьОбъектыПоСсылкам);
				
			КонецЕсли;
			
			ПроверитьНачалоИФиксациюТранзакцииПриЗагрузкеДанных();
			
		КонецЦикла;
		
		Если ОбъектМетаданныхПредыдущий <> Неопределено Тогда
			
			// {ОБРАБОТЧИК ПослеОбработки ПВД}
			Если ПравилоВыгрузкиДанных <> Неопределено
				И Не ПустаяСтрока(ПравилоВыгрузкиДанных.ПослеОбработки) Тогда
				
				Попытка
					
					Если ОтладкаОбработчиковВыгрузки Тогда
						
						ВыполнитьОбработчик_ПВД_ПослеОбработкиПравила(ИмяПКО, ПравилоВыгрузкиДанных, ИсходящиеДанные);
						
					Иначе
						
						Выполнить(ПравилоВыгрузкиДанных.ПослеОбработки);
						
					КонецЕсли;
					
				Исключение
					ЗаписатьИнформациюОбОшибкеОбработчикиПВД(32, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
						ПравилоВыгрузкиДанных.Имя, "ПослеОбработкиВыгрузкиДанных");
				КонецПопытки;
				
			КонецЕсли;
			// {ОБРАБОТЧИК ПослеОбработки ПВД}
			
		КонецЕсли;
	
		ЗафиксироватьТранзакциюПриЗагрузкеДанных();
		
	Исключение
		
		ОтменитьТранзакциюПриЗагрузкеДанных();
		
		ВызватьИсключение(НСтр("ru = 'Ошибка при отправке данных'") + ": " + ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		
	КонецПопытки
	
КонецПроцедуры

Процедура НачатьТранзакциюПриЗагрузкеДанных()
	
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		Если ЗагрузкаДанныхВыполняетсяВоВнешнемСоединении Тогда
			Если ОбработкаДляЗагрузкиДанных().ИспользоватьТранзакции Тогда
				ВнешнееСоединение.НачатьТранзакцию();
			КонецЕсли;
		Иначе
			ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеНачатьТранзакциюПриЗагрузкеДанных();
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Процедура ПроверитьНачалоИФиксациюТранзакцииПриЗагрузкеДанных()
	
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		Если ЗагрузкаДанныхВыполняетсяВоВнешнемСоединении Тогда
			Если ОбработкаДляЗагрузкиДанных().ИспользоватьТранзакции
				И ОбработкаДляЗагрузкиДанных().КоличествоОбъектовНаТранзакцию > 0
				И ОбработкаДляЗагрузкиДанных().СчетчикЗагруженныхОбъектов() % ОбработкаДляЗагрузкиДанных().КоличествоОбъектовНаТранзакцию = 0 Тогда
				
				// Если используются транзакции и установлено количество элементов одной транзакции,
				// то при чтении сообщения обмена необходимо контролировать,
				// сколько объектов загружено. Если количество загруженных объектов 
				// равно количество объектов в одной транзакции, то существующую транзакцию
				// необходимо зафиксировать и открыть новую.
				ВнешнееСоединение.ЗафиксироватьТранзакцию();
				ВнешнееСоединение.НачатьТранзакцию();
			КонецЕсли;
		Иначе
			ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеПроверитьНачалоИФиксациюТранзакцииПриЗагрузкеДанных();
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Процедура ЗафиксироватьТранзакциюПриЗагрузкеДанных()
	
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		Если ЗагрузкаДанныхВыполняетсяВоВнешнемСоединении Тогда
			Если ОбработкаДляЗагрузкиДанных().ИспользоватьТранзакции Тогда
				Если ОбработкаДляЗагрузкиДанных().ФлагОшибки() Тогда
					ВызватьИсключение(НСтр("ru = 'Ошибка при отправке данных.'"));
				Иначе
					ВнешнееСоединение.ЗафиксироватьТранзакцию();
				КонецЕсли;
			КонецЕсли;
		Иначе
			ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеЗафиксироватьТранзакциюПриЗагрузкеДанных();
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Процедура ОтменитьТранзакциюПриЗагрузкеДанных()
	
	Если ЭтоОбменЧерезВнешнееСоединение() Тогда
		Если ЗагрузкаДанныхВыполняетсяВоВнешнемСоединении Тогда
			Пока ВнешнееСоединение.ТранзакцияАктивна() Цикл
				ВнешнееСоединение.ОтменитьТранзакцию();
			КонецЦикла;
		Иначе
			ОбработкаДляЗагрузкиДанных().ВнешнееСоединениеОтменитьТранзакциюПриЗагрузкеДанных();
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры


Процедура ЗаписьЖурналаРегистрацииОбменДанными(Комментарий, Уровень = Неопределено)
	
	Если Уровень = Неопределено Тогда
		Уровень = УровеньЖурналаРегистрации.Ошибка;
	КонецЕсли;
	
	ОбъектМетаданных = Неопределено;
	
	Если     УзелОбменаЗагрузкаДанных <> Неопределено
		И Не УзелОбменаЗагрузкаДанных.Пустая() Тогда
		
		ОбъектМетаданных = УзелОбменаЗагрузкаДанных.Метаданные();
		
	КонецЕсли;
	
	ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации(), Уровень, ОбъектМетаданных,, Комментарий);
	
КонецПроцедуры

Функция ВыгрузитьИнформациюСопоставленияОбъектов(УзелИнформационнойБазы)
	
	ТекстЗапроса = "
	|ВЫБРАТЬ ПЕРВЫЕ 1 1
	|ИЗ
	|	РегистрСведений.СоответствияОбъектовИнформационныхБаз.Изменения КАК СоответствияОбъектовИнформационныхБазИзменения
	|ГДЕ
	|	СоответствияОбъектовИнформационныхБазИзменения.Узел = &УзелИнформационнойБазы
	|";
	
	Запрос = Новый Запрос;
	Запрос.Текст = ТекстЗапроса;
	Запрос.УстановитьПараметр("УзелИнформационнойБазы", УзелИнформационнойБазы);
	
	Возврат Не Запрос.Выполнить().Пустой();
	
КонецФункции

Функция НеобходимоВыполнитьКорректировкуИнформацииСопоставления()
	
	Возврат РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.НеобходимоВыполнитьКорректировкуИнформацииСопоставления(УзелДляОбмена, УзелДляОбмена.НомерОтправленного + 1);
	
КонецФункции

Процедура УдалитьНедопустимыеЗначенияИзМассиваВыгружаемыхМетаданных(МассивВыгружаемыхМетаданных)
	
	Если МассивВыгружаемыхМетаданных.Найти(Неопределено) <> Неопределено Тогда
		
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(МассивВыгружаемыхМетаданных, Неопределено);
		
		УдалитьНедопустимыеЗначенияИзМассиваВыгружаемыхМетаданных(МассивВыгружаемыхМетаданных);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ДополнитьМассивВыгружаемыхМетаданныхКонстантами(МассивВыгружаемыхМетаданных)
	
	Состав = Метаданные.ПланыОбмена[ИмяПланаОбмена()].Состав;
	
	Для Каждого ОбъектМетаданныхКонстанта Из Метаданные.Константы Цикл
		
		Если Состав.Содержит(ОбъектМетаданныхКонстанта) Тогда
			
			МассивВыгружаемыхМетаданных.Добавить(ОбъектМетаданныхКонстанта);
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ЗаписатьПакетВФайлДляСборкиАрхива(Источник)
	
	Если НЕ ПоместитьСообщениеВАрхивПриВнешнемСоединении Тогда
		Возврат;
	КонецЕсли;
	
	ИмяФайла = ВременныйКаталогДляСборкиАрхива + НомерПакета + ".xml";
	НомерПакета = НомерПакета + 1;
	
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.ДобавитьСтроку(Источник);
	ТекстовыйДокумент.Записать(ИмяФайла, , Символы.ПС);
	
КонецПроцедуры

Процедура СобратьИПоместитьСообщениеОбменаВАрхив()

	Если НЕ ПоместитьСообщениеВАрхивПриВнешнемСоединении Тогда
		Возврат;
	КонецЕсли;
	
	ИмяОбщегоФайла = ВременныйКаталогДляСборкиАрхива + Строка(Новый УникальныйИдентификатор) + ".xml";

	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	
	Для Сч = 0 По (НомерПакета - 1) Цикл
		
		ИмяФайла = ВременныйКаталогДляСборкиАрхива + Сч + ".xml";
		Чтение = Новый ЧтениеТекста(ИмяФайла);
		Строка = Чтение.Прочитать();
		Чтение = Неопределено;
		
		ТекстовыйДокумент.ДобавитьСтроку(Строка);
		
	КонецЦикла;
	
	ТекстовыйДокумент.ДобавитьСтроку("</ФайлОбмена>");
	ТекстовыйДокумент.Записать(ИмяОбщегоФайла, , Символы.ПС);
	ТекстовыйДокумент = Неопределено;
	
	РегистрыСведений.АрхивСообщенийОбменов.ПоместитьСообщениеВАрхив(УзелОбменаЗагрузкаДанных, ИмяОбщегоФайла);
	
	УдалитьФайлы(ВременныйКаталогДляСборкиАрхива);
	
КонецПроцедуры

Процедура ЗаписатьЗаголовокСообщенияДляАрхива()
	
	ИмяФайла = ВременныйКаталогДляСборкиАрхива +  НомерПакета + ".xml";
	
	НомерПакета = НомерПакета + 1;
	
	ФайлОбмена = Новый ЗаписьТекста;
	ФайлОбмена.Открыть(ИмяФайла, КодировкаТекста.UTF8);
	
	СтрокаИнформацииОXML = "<?xml version=""1.0"" encoding=""UTF-8""?>";
	
	ФайлОбмена.ЗаписатьСтроку(СтрокаИнформацииОXML);

	ВременныйЗаписьXML = Новый ЗаписьXML();
	
	ВременныйЗаписьXML.УстановитьСтроку();
	
	ВременныйЗаписьXML.ЗаписатьНачалоЭлемента("ФайлОбмена");
	
	УстановитьАтрибут(ВременныйЗаписьXML, "ВерсияФормата", 				 ВерсияФорматаСообщенияОбмена());
	УстановитьАтрибут(ВременныйЗаписьXML, "ДатаВыгрузки",				 ТекущаяДатаСеанса());
	УстановитьАтрибут(ВременныйЗаписьXML, "ИмяКонфигурацииИсточника",	 Конвертация().Источник);
	УстановитьАтрибут(ВременныйЗаписьXML, "ВерсияКонфигурацииИсточника", Конвертация().ВерсияКонфигурацииИсточника);
	УстановитьАтрибут(ВременныйЗаписьXML, "ИмяКонфигурацииПриемника",	 Конвертация().Приемник);
	УстановитьАтрибут(ВременныйЗаписьXML, "ИдПравилКонвертации",		 Конвертация().Ид);
	
	ВременныйЗаписьXML.ЗаписатьКонецЭлемента();
	
	Стр = ВременныйЗаписьXML.Закрыть();
	
	Стр = СтрЗаменить(Стр, "/>", ">");
	
	ФайлОбмена.ЗаписатьСтроку(Стр);
	
	ФайлОбмена.Закрыть();
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область Инициализация

ИнициализацияРеквизитовИМодульныхПеременных();

ИнициализацияТаблицыПравилКонвертации();
ИнициализацияТаблицыПравилВыгрузки();
ИнициализацияТаблицыПравилОчистки();
ИнициализацияТаблицыНастройкиПараметров();

#КонецОбласти

#Иначе
ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'");
#КонецЕсли
